#23754 closed Bug (fixed)
DisallowedModelAdminToField when using get_inline_instances()
Reported by: | Tim Graham | Owned by: | Simon Charette |
---|---|---|---|
Component: | contrib.admin | Version: | 1.4 |
Severity: | Release blocker | Keywords: | |
Cc: | Simon Charette, Julien Phalip | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
As reported in the comments of #23552:
models.py
class Invoice(models.Model): ... class Payment(models.Model): ... class InvoicePayment(models.Model): payment = models.OneToOneField(Payment) invoice = models.ForeignKey(Invoice)
admin.py:
class InvoicePaymentInline(admin.StackedInline): model = InvoicePayment extra = 1 class InvoiceAdmin(admin.ModelAdmin): #Using sample code from https://docs.djangoproject.com/en/1.7/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_inline_instances def get_inline_instances(self, request, obj=None): return [inline(self.model, self.admin_site) for inline in [InvoicePaymentInline]] # Register your models here. admin.site.register(Invoice, InvoiceAdmin) admin.site.register(Payment, )
In admin, from invoice change_form, click on "+" button next payment in inlines display popup with "bad request 400"
Change History (15)
comment:1 by , 10 years ago
comment:2 by , 10 years ago
Severity: | Release blocker → Normal |
---|
How about the documentation route, at least for older versions of Django? Then we can revisit the issue using 3 if you feel that will be less problematic going forward.
comment:3 by , 10 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
Good idea, let's document this as a requirement for older versions of Django. I should be able to come up with a draft in the next few days.
comment:4 by , 10 years ago
Cc: | added |
---|---|
Has patch: | set |
Severity: | Normal → Release blocker |
#23839 was a duplicate.
After further analysis I think the correct solution would be to backport the fix proposed by @jphalip there which is to always allow reference to the primary key of the model instead to avoid documenting to_field_allowed()
and expose a security foot-gun.
Since the admin doesn't currently work with many to many through a model pointing to a non-primary key field (see #23862) the only remaining edge case would be dealing with dynamically generated inlines with a foreign key pointing to a non-primary key field. For this case I suggest we follow comment:1 suggestion to document that get_inline_instances()
should always return instances of a subset of the classes defined in inlines
.
Since the initial to_field_allowed
patch introduced many regression I'll try to get feedback from the developer mailing list before committing to this solution.
Patch should follow shortly.
comment:10 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
The
to_field
check is failing here because it only collects statically defined inline classes for its sanity checks. This could be solved by one of the following:get_inline_instances()
should always return instances of a subset of the classes defined ininlines
.to_field_allowed()
and link to itget_inline_instances()
's documentation noting that it might require overriding if1.
criteria is not met.Given the many regression caused by the inner admin site references enforcement I think
3.
might be our best option. Thoughts?