Opened 16 years ago

Last modified 13 years ago

#7918 closed

Allow ForeignKey to a parent class when using inlines — at Version 3

Reported by: sil Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Keywords:
Cc: arnaud.rebts@… Triage Stage: Accepted
Has patch: yes Needs documentation: yes
Needs tests: yes Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Brian Rosner)

At the moment, if you have a hierarchy:

class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)

class Restaurant(Place):
    serves_hot_dogs = models.BooleanField()
    serves_pizza = models.BooleanField()

(as per http://www.djangoproject.com/documentation/model-api/#multi-table-inheritance), it doesn't interact all that well with inlined ForeignKeyed models. Imagine you had:

class Owner:
    name = models.CharField(max_length=100)
    place = models.ForeignKey(Place)

(so a Place can have multiple Owners). This also works fine with Restaurants, because every Restaurant is-a Place. However, if you want to inline the Owners:

class OwnerInline(admin.TabularInline): 
    model = Owner
    extra = 5

class PlaceAdmin(admin.ModelAdmin):
    model = Place
    inlines = [OwnerInline]

then this won't work; if you try and create a Restaurant, you get a complaint that Owner has no ForeignKey to Restaurant (because technically it doesn't). This is because (new)forms._get_foreign_key checks that the ForeignKey points to this model itself, where it should really be checking whether the ForeignKey points to this model or any of its ancestor classes. The attached patch rectifies this.

Change History (3)

comment:1 by sil, 16 years ago

mrph. Code from above in code formatting. Sorry.

class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)

class Restaurant(Place):
    serves_hot_dogs = models.BooleanField()
    serves_pizza = models.BooleanField?()

class Owner:
    name = models.CharField(max_length=100)
    place = models.ForeignKey(Place)

class OwnerInline(admin.TabularInline):
    model = Owner
    extra = 5

class PlaceAdmin(admin.ModelAdmin):
    model = Place
    inlines = [OwnerInline]

comment:2 by sil, 16 years ago

Needs documentation: set
Needs tests: set
Patch needs improvement: set

comment:3 by Brian Rosner, 16 years ago

Description: modified (diff)

Fixed ticket description formatting.

Note: See TracTickets for help on using tickets.
Back to Top