Opened 20 years ago
Closed 20 years ago
#1245 closed defect (fixed)
[patch] Admin interface broken for OneToOne relations
| Reported by: | gattomatto | Owned by: | Adrian Holovaty | 
|---|---|---|---|
| Component: | contrib.admin | Version: | 0.91 | 
| Severity: | major | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | yes | Needs documentation: | no | 
| Needs tests: | no | Patch needs improvement: | no | 
| Easy pickings: | UI/UX: | 
Description
We inserted the Places and Restaurantes code verbatim as in example http://www.djangoproject.com/documentation/models/one_to_one/.
We addes META classes with an admin attribute (only), to activate the Admin interface.
If we try to administer the Restaurants objects, we got this error on Postgresql:
ProgrammingError at /admin/exemplemodel/restaurants/ ERROR: missing FROM-clause entry for table "exemplemodel_places" SELECT "exemplemodel_restaurants"."place_id","exemplemodel_restaurants"."serves_hot_dogs","exemplemodel_restaurants"."serves_pizza" FROM "exemplemodel_restaurants" ORDER BY "exemplemodel_places"."id" DESC )
If the Postgres database is configured with "add_missing_from = true", which is the default, you don't get any error but Restaurants lines get listed twice, because of a cartesian product between the two tables.
We think that the ORDER BY clause is generated incorrectly, citing the wrong table/object.
We're using Django 0.91.
Attachments (1)
Change History (7)
comment:1 by , 20 years ago
comment:2 by , 20 years ago
| Version: | → 0.91 | 
|---|
Same problem here. Two hints, FWIW:
- the get_list() method works fine (no duplicate),
 - adding an 'ordering' in the class declaring the OneToOneField solves the problem in the admin ChangeList.
 
comment:4 by , 20 years ago
| Summary: | Admin interface broken for OneToOne relations → [patch] Admin interface broken for OneToOne relations | 
|---|
Hi, I recently found this problem too. 
I found that when the view is constructing the lookup_order_field, it tests if the ordering field is a foreign key like this:
if isinstance(lookup_opts.get_field(order_field).rel, meta.ManyToOneRel):
    f = lookup_opts.get_field(order_field)
    rel_ordering = f.rel.to.ordering and f.rel.to.ordering[0] or f.rel.to.pk.column
    lookup_order_field = '%s.%s' % (f.rel.to.db_table, rel_ordering)
But since a OneToOneRel is also an istance of a ManyToOneRel, that isinstance() evaluates to true, thus constructing this incorrect lookup_order_field (as shown in the problem description above):
"examplemodel_places"."id"
What I did was to first test if the field is a OneToOne field and construct the lookup_order_field correctly:
f = lookup_opts.get_field(order_field)
if isinstance(f.rel, meta.OneToOneRel):
    lookup_order_field = '%s' % (f.column,)
elif isinstance(f.rel, meta.ManyToOneRel):
    rel_ordering = f.rel.to.ordering and f.rel.to.ordering[0] or f.rel.to.pk.column
    lookup_order_field = '%s.%s' % (f.rel.to.db_table, rel_ordering)
I'm attaching a patch.
I'm not really familiar with all the rest of the code, so it may be possible that I'm not considering other circumstances but I have had no problems so far. 
Thanks.
by , 20 years ago
| Attachment: | admin_views_main.diff added | 
|---|
Fix lookup_order_field for OneToOne fields
comment:5 by , 20 years ago
| priority: | normal → high | 
|---|---|
| Severity: | normal → major | 
comment:6 by , 20 years ago
| Resolution: | → fixed | 
|---|---|
| Status: | new → closed | 
I am getting a similar error where I get duplicate entries in the admin interface. I have the following:
class Blurb(meta.Model): [...] class Photo(meta.Model): blurb = meta.OneToOneField(Blurb) class Journal(meta.Model): blurb = meta.OneToOneField(blurb)The more Blurbs that get added, the crazier the duplicates that occur in the Photo and Journal interfaces. This behavior seems to indicate it's a matter of adding a where clause in the query that joins the Journal's id with the blurb's id.