0

In the app I'm building some users have the role "Coder" and are assigned to "Assignments".
What I can't seem to get working is the process of an Admin assigning Coders to Assignments.

Here is the Model-Code I have so far (probably totally wrong):

class Coder(models.Model):
"""Every user can be a coder. Coders are assigned to Assignments"""
user = models.OneToOneField(User)

class Admin:
    list_display = ('',)
    search_fields = ('',)

def __unicode__(self):
    return u"Coders"

class Assignment(models.Model):
"""(Assignment description)"""
title = models.CharField(blank=True, max_length=100)
start_year = models.IntegerField(blank=True, null=True)
end_year = models.IntegerField(blank=True, null=True)
country = models.IntegerField(blank=True, null=True)
coders = models.ManyToManyField(Coder)

class Admin:
    list_display = ('',)
    search_fields = ('',)

def __unicode__(self):
    return u"Assignment"

And this is the admin-code:

class AssignmentCoderInline(admin.StackedInline):
model = Assignment.coders.through
can_delete = False
verbose_name_plural = 'coder'

class AssignmentAdmin(admin.ModelAdmin):
fieldsets = [
    ('Assignment', {'fields': ['title', 'start_year', 'end_year']})
]
inlines = (AssignmentCoderInline,)

class CoderInline(admin.StackedInline):
model = Coder
can_delete = False
verbose_name_plural = 'coder'

Now, when i'm in the admin, I want to create an assignment and add coders to it. Yet all I see when trying to do so is this:
This is what I see in the admin

How can I add one coder/user to an assignment, so I can later show him in a view all the assignments he has? This is probably a really dumb question, but please answer anyways, I greatly appreciate any help :)

LukasKawerau
  • 1,071
  • 2
  • 23
  • 42

1 Answers1

1

If I'm not mistaken, it looks like you want to call a coder to a view, and then show all the assignments for an a user.

First, I might start by assigning a related_name to the coder and assignment models relationships with each other, so you can easily reference them later.

class Assignment(models.Model):
    coders = models.ManyToManyField(Coder, related_name='assignments')

class Coder(models.Model):
    user = models.OneToOneField(User, related_name="coder")

I'd then reference the user in a template as such using the one to one relationship:

    {% for assignment in user.coder.assignments.all %}

Also, looks like the problem is how you've got yout models setup. After reviewing the django.db.models.base for the "models.Model" class and "ModelBase" class, it looks like there is no "Admin" subclass. You'll probably want to remove those to start with.

Next, the __unicode__ field shows the default visible value which represents the object on the screen. In this case, you've forced it to be "Coders". If you had 5 coders to an assignment, you'd see "Coders, Coders, Coders, Coders, Coders" instead of "admin, user1, bob22, harry8, stadm1in", etc. Let's override the unicode to show something more meaningful. Since the coders field only has the user field, let's reference that by self.user.username. We'll change Assignment()'s unicode to self.title as well.

ModelForm doesn't have an 'Admin' subclass either, so let's remove that.

MODELS:


class Coder(models.Model):
    """Every user can be a coder. Coders are assigned to Assignments"""
    user = models.OneToOneField(User, related_name='coder')

    def __unicode__(self):
        return self.user.username


class Assignment(models.Model):
    """(Assignment description)"""
    title = models.CharField(blank=True, max_length=100)
    start_year = models.IntegerField(blank=True, null=True)
    end_year = models.IntegerField(blank=True, null=True)
    country = models.IntegerField(blank=True, null=True)
    coders = models.ManyToManyField(Coder, related_name='assignments')

    def __unicode__(self):
        return self.title


ADMIN:

class AssignmentCoderInline(admin.StackedInline):
    model = Assignment.coders.through
    can_delete = False
 #   verbose_name_plural = 'coder'

class AssignmentAdmin(admin.ModelAdmin):
    fieldsets = [
        ('Assignment', {'fields': ['title', 'start_year', 'end_year']})
    ]
    inlines = (AssignmentCoderInline,)
Tim Selaty Jr.
  • 599
  • 4
  • 6
  • This is helpful, thank you! On thing isn't answered for me though: How do I assign on or many users (=coders) to an assignment in the admin? That doesn't work and I would really like to know how I could make it work :) – LukasKawerau Apr 20 '13 at 09:30
  • Well, it looks like you've already got that setup. When you go to an assignment in the backend administrative panel, http://i.stack.imgur.com/Omhuu.png allows you to add more coders (multiple coders) to a single assignment. If I'm not mistaken that's what you're looking for. – Tim Selaty Jr. Apr 20 '13 at 09:33
  • Also, it could be the fact that you're returning __unicode__ as "coders". Mind if you share the whole admin.py and models.py in a pastebin.com snippet? – Tim Selaty Jr. Apr 20 '13 at 09:35
  • Yes, but my problem is that I can't choose which coder to assign. All I see is "Coders", but have no way of saying "John Smith should do this assignment". How do I do that? – LukasKawerau Apr 20 '13 at 09:35
  • I've updated my answer with what should be the closest resolution to your question. – Tim Selaty Jr. Apr 20 '13 at 10:07
  • This is awesome, thank you! One thing: If I reference [CoderInline,] instead of [AssignmentCoderInline,] I get " has no ForeignKey to ". With AssignmentCoderInline it works perfectly though, thanks :) – LukasKawerau Apr 20 '13 at 10:26
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/28552/discussion-between-lukaskawerau-and-tim-selaty-jr) – LukasKawerau Apr 20 '13 at 10:35