views:

37

answers:

2

Hi,

I have the following model:

class Program(models.Model):
    name = models.CharField(max_length = 128)
    def __unicode__(self):
        return self.name
class Cheat(models.Model):
    program = models.ForeignKey(Program)
    shortcut = models.CharField(max_length = 64)
    description = models.CharField(max_length = 512)
    def __unicode__(self):
        return u"(%s) - %s" % (self.shortcut, self.description)
class Category(models.Model):
    #program = models.ForeignKey(Program)
    name = models.CharField(max_length = 128)
    def __unicode__(self):
        return self.name
class Sheet(models.Model):
    program = models.ForeignKey(Program)
    name = models.CharField(max_length = 128)
    def __unicode__(self):
        return self.name
class CategorizedCheat(models.Model):
    order = models.IntegerField(unique = True)
    sheet = models.ForeignKey(Sheet)
    cheat = models.ForeignKey(Cheat)
    category = models.ForeignKey(Category)
    def __unicode__(self):
        return unicode(self.cheat)

In the admin, I want to display a Sheet with CategorizedCheats inline. The problem is that I'm unable to have only Cheat that are related to the same Program as the Sheet. Is there a way to filter thoses with the Sheet.program ? Or is there something wrong with my models ?

+1  A: 

When filtering the available objects in ForeignKeys within Django's admin, the right answer is pretty much always ModelAdmin.formfield_for_foreignkey:

http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_for_foreignkey

The docs there explain how to do almost exactly what you're looking for. Hope that helps!

Gabriel Hurley
Yeah I thought of that function, unfortunately, I do not know what to put in the queryset, how do I know my own self.program ?That is, class MySheetAdmin(admin.ModelAdmin), how do I access the current Sheet.program ? From that this is pretty straightforward.
slurdge
A: 

Here is the final solution thanks to Gabriel:

def formfield_for_foreignkey(self, db_field, request, **kwargs):
    if db_field.name == "cheat":
        kwargs["queryset"] = Cheat.objects.filter(program=Sheet.objects.get().program)
        return db_field.formfield(**kwargs)
    return super(CategorizedCheatAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

The trick was to use Sheet.objects.get().program, this was the information I was lacking.

slurdge