Opened 6 years ago

Closed 6 years ago

#9461 closed (fixed)

raw id fields for inherited models in inline intermediate models show base class __unicode__ rather than id

Reported by: Jacob Smullyan <jsmullyan@…> Owned by: mtredinnick
Component: contrib.admin Version: 1.0
Severity: Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

A raw id field targetting a model that inherits concretely from another, when appearing in an intermediate model's inline in a m2m field, will be populated upon selection, not with an id, but with a string representation of the target model's base class (which breaks). That's accurate but a bit opaque. Here is an example:

from django.contrib import admin
from django.contrib.contenttypes import generic
from django.db import models

class Base(models.Model):
    title=models.CharField(max_length=80)
    
class X(Base):
    number=models.IntegerField()

class Y(models.Model):
    some_as=models.ManyToManyField(X, through='X2YRelation')
    
class X2YRelation(models.Model):
    sort_number=models.IntegerField()
    x=models.ForeignKey(X)
    y=models.ForeignKey(Y)
    
admin.site.register(X)

class X2YInline(admin.TabularInline):
    model=X2YRelation
    raw_id_fields=('x',)

class YAdmin(admin.ModelAdmin):
    inlines=[X2YInline]

admin.site.register(Y, YAdmin)    

If you run this and go in the admin to create a Y object, you can successfully create an X inline, but you cannot choose an existing X, because instead of an id showing up in the raw id field, you get the string "Base object", which of course makes the form blow up on submit.

The ramifications of this bug in a real life application, from which the above example is abstracted, are pretty severe, since dropdowns aren't really usable when the number of choices is unlimited -- and inline's extras cause the dropdown to be repeated, making things even worse. A workaround is to set the __unicode__ of the base class to return u"%d" % self.id , but that makes __unicode__ useless for other purposes.

(Note: I'm running the 1.0.X branch, but I've also tested the above example on trunk.)

Change History (2)

comment:1 Changed 6 years ago by mtredinnick

  • Needs documentation unset
  • Needs tests unset
  • Owner changed from nobody to mtredinnick
  • Patch needs improvement unset
  • Status changed from new to assigned

Closing #9730 as a dupe of this. Only noting that here because #9730 contains another full example if it's needed.

comment:2 Changed 6 years ago by mtredinnick

  • Resolution set to fixed
  • Status changed from assigned to closed

(In [9602]) The second part of fixing "related inherited models" display. Handle raw_id values for child models in the admin. Fixed #9461.

I couldn't think of a way to test this automatically and robustly, however,
manual testing with the ticket example shows failure before and success
afterwards and the fix make sense logically.

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