Opened 3 years ago

Closed 3 years ago

#18059 closed Bug (wontfix)

Admin inlines appear to be blind to releated_name relations

Reported by: shayne.oneill@… Owned by: nobody
Component: contrib.admin Version: 1.4
Severity: Normal Keywords: admin inline reverse_name
Cc: Triage Stage: Design decision needed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When using Inline admin fields, it appears to be impossible to inline the target of a ForeignKey relationship as the inline record does not have an explicit relationship but an Implicit relationship.

This seems erroneous. I am unsure if this was broken recently, or has always been the case, so I dont know if its a "normal" bug or "release blocker" bug. Obviously its not a happy state of affairs however.

Change History (6)

comment:1 Changed 3 years ago by anonymous

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Summary changed from Admin inlines appear to be blind to reverse_name relations to Admin inlines appear to be blind to releated_name relations

By "reverse_name" read "related_name". Sorry, its been a late night.

comment:2 Changed 3 years ago by julien

I'm not entirely sure what problem you're facing. Could you provide a snippet of code that you expect should work but doesn't?

comment:3 Changed 3 years ago by anonymous

Ah , I cant give code because of an NDA, but I can explain it.

I have 3 models. A doctor, a Patient, and a Consent form.

The consent form has two foreignKey relationships. One to the doctor and one to the patient.

So something like Doctor <-1----M-> Consent form <-M----1-> The idea is that a patient might have multiple consent forms (One per doctor) and the doctor will have multiple consent forms (One per patient) but a consent form will have just one doctor and one patient.

So thus, I want to display the consent form in the admin area, with the details of the doctor and patient in an inline form.

The problem is, when I do this, it complains that there is no foreignkey back to the form. I had assumed this ought be covered by the related_name in the ForeignKey fields on Doctor and Patient, but apparently this is not so. I'm not sure why this isn't sufficient, or is there some reason why the 'parent' records can't be inline, in general. It seems a bit of a show stopper. :(

comment:4 Changed 3 years ago by julien

Thanks for the explanation. However I'm still unclear about how that would translate into code, in particular: "I want to display the consent form in the admin area, with the details of the doctor and patient in an inline form."

So it would really help if you could provide some sample code. Thanks!

comment:5 Changed 3 years ago by gabejackson

  • Triage Stage changed from Unreviewed to Design decision needed

He is expecting the following code to work:

models.py:

from django.db import models

class Patient(models.Model):
    name = models.CharField(max_length=200)

    def __unicode__(self):
        return self.name

class Doctor(models.Model):
    name = models.CharField(max_length=200)

    def __unicode__(self):
        return self.name
        
class Consent(models.Model):
    doctor = models.ForeignKey(Doctor)
    patient = models.ForeignKey(Patient)

admin.py:

from django.contrib import admin

from bug_18059.models import *

class DoctorInline(admin.TabularInline):
    model = Doctor

class PatientInline(admin.TabularInline):
    model = Patient

class ConsentAdmin(admin.ModelAdmin):
    inlines = [
        DoctorInline,
        PatientInline,
    ]

admin.site.register(Consent, ConsentAdmin)

This will lead to the following exception:

Traceback:
File "/Users/Gabe/venv/django/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/Users/Gabe/venv/django/lib/python2.7/site-packages/django/contrib/admin/options.py" in wrapper
  366.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/Gabe/venv/django/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  91.                     response = view_func(request, *args, **kwargs)
File "/Users/Gabe/venv/django/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  89.         response = view_func(request, *args, **kwargs)
File "/Users/Gabe/venv/django/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner
  196.             return view(request, *args, **kwargs)
File "/Users/Gabe/venv/django/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
  25.             return bound_func(*args, **kwargs)
File "/Users/Gabe/venv/django/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
  91.                     response = view_func(request, *args, **kwargs)
File "/Users/Gabe/venv/django/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
  21.                 return func(self, *args2, **kwargs2)
File "/Users/Gabe/venv/django/lib/python2.7/site-packages/django/db/transaction.py" in inner
  209.                 return func(*args, **kwargs)
File "/Users/Gabe/venv/django/lib/python2.7/site-packages/django/contrib/admin/options.py" in add_view
  972.             for FormSet, inline in zip(self.get_formsets(request), inline_instances):
File "/Users/Gabe/venv/django/lib/python2.7/site-packages/django/contrib/admin/options.py" in get_formsets
  507.             yield inline.get_formset(request, obj)
File "/Users/Gabe/venv/django/lib/python2.7/site-packages/django/contrib/admin/options.py" in get_formset
  1413.         return inlineformset_factory(self.parent_model, self.model, **defaults)
File "/Users/Gabe/venv/django/lib/python2.7/site-packages/django/forms/models.py" in inlineformset_factory
  817.     fk = _get_foreign_key(parent_model, model, fk_name=fk_name)
File "/Users/Gabe/venv/django/lib/python2.7/site-packages/django/forms/models.py" in _get_foreign_key
  800.             raise Exception("%s has no ForeignKey to %s" % (model, parent_model))

Exception Type: Exception at /admin/bug_18059/consent/add/
Exception Value: <class 'bug_18059.models.Doctor'> has no ForeignKey to <class 'bug_18059.models.Consent'>

What he is expecting (I think) is a Consent Form which allows you to create a Doctor and Person directly in the Consent Form.

comment:6 Changed 3 years ago by kmtracey

  • Resolution set to wontfix
  • Status changed from new to closed

The described scenario is not what admin inlines are for. Admin inlines allow displaying the "many" side of the relation on the edit page for the "one". So you could put the multiple consent forms associated with a single doctor on the edit page for the doctor, likewise you could put consent forms inline on the edit page for patient. On the edit page for consent form itself you have the ability to choose the single doctor you want to associate with the form, and the single patient. If either of those don't yet exist you can press the green plus icon to go to a page where you can create a new one. But you cannot edit the details of the associated object (doctor or patient) on the page for editing the consent form, and that sort of thing is not what inlines are intended to do.

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