Opened 10 years ago

Closed 9 years ago

#1245 closed defect (fixed)

[patch] Admin interface broken for OneToOne relations

Reported by: gattomatto Owned by: adrian
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)

admin_views_main.diff (936 bytes) - added by Jorge Gajon <gajon@…> 9 years ago.
Fix lookup_order_field for OneToOne fields

Download all attachments as: .zip

Change History (7)

comment:1 Changed 10 years ago by berto

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.

comment:2 Changed 9 years ago by bruno@…

  • Version set to 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:3 Changed 9 years ago by bruno@…

After a bit more search here, it seems to be the same problem as #930.

comment:4 Changed 9 years ago by Jorge Gajon <gajon@…>

  • Summary changed from Admin interface broken for OneToOne relations to [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.

Changed 9 years ago by Jorge Gajon <gajon@…>

Fix lookup_order_field for OneToOne fields

comment:5 Changed 9 years ago by Jorge Gajon <gajon@…>

  • priority changed from normal to high
  • Severity changed from normal to major

Upping the priority since the admin interface is unusable when this problem appears.

Tickets #877 and #930 describe the same problem, they could be marked as duplicates.

comment:6 Changed 9 years ago by jkocherhans

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

(In [2720]) magic-removal: fixed #1245. For models with a OneToOneField and no ordering specified, the admin change_list now orders by the OneToOneField rather than trying to order by the related object's ordering. Use the ordering and list_select_related options to do otherwise.

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