#7918 closed (fixed)
Allow ForeignKey to a parent class when using inlines
Reported by: | sil | Owned by: | Brian Rosner |
---|---|---|---|
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 )
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.
Attachments (1)
Change History (16)
comment:1 by , 16 years ago
comment:2 by , 16 years ago
Needs documentation: | set |
---|---|
Needs tests: | set |
Patch needs improvement: | set |
comment:4 by , 16 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
Triage Stage: | Unreviewed → Accepted |
Version: | newforms-admin → SVN |
comment:5 by , 16 years ago
milestone: | → 1.0 beta |
---|
comment:6 by , 16 years ago
Updated patch to handle the OneToOneField value being null when you're first adding a Restaurant, which blows up because it's not a nullable field (since it's a PK) but doesn't have a value (because the Restaurant isn't saved yet). Sorry.
comment:7 by , 16 years ago
Patch needs improvement: | unset |
---|---|
Triage Stage: | Accepted → Unreviewed |
comment:8 by , 16 years ago
Triage Stage: | Unreviewed → Accepted |
---|
Don't change the stage. That is reserved for ticket triagers and committers. The ticket itself is accepted, you don't need to do that when you upload a new patch. The needs_better_patch is meant for that :)
comment:10 by , 16 years ago
It is likely [8165] has fixed this. Can someone verify? Perhaps a test case should be ordered :)
comment:11 by , 16 years ago
milestone: | 1.0 beta → 1.0 |
---|
comment:12 by , 16 years ago
Cc: | added |
---|
It seems to be working now if the ForeinKey is in the direct super class, but not if it's in a higher class.
So, this is working:
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(models.Model): 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] class RestaurantAdmin(admin.ModelAdmin): model = Restaurant inlines = [OwnerInline]
But not this:
class ItalianRestaurant(Restaurant): pass class ItalianRestaurantAdmin(admin.ModelAdmin): model = ItalianRestaurant inlines = [OwnerInline]
comment:13 by , 16 years ago
Component: | Uncategorized → Database wrapper |
---|
comment:14 by , 16 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
mrph. Code from above in code formatting. Sorry.