Opened 12 years ago

Closed 12 years ago

Last modified 12 years ago

#18507 closed Uncategorized (worksforme)

Django 1.3 breaks ordering by the reverse of a one-to-one field

Reported by: Klaas van Schelven Owned by: nobody
Component: Database layer (models, ORM) Version: 1.3
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I have a piece of code that breaks on migrating from 1.2 to 1.3. There is no mention of this in the 1.3 release notes, specifically in the section that speaks of backwards incompatibilities.

Basically, I'm poking the order_by value on User's Meta to be ordered by properties of UserProfile. UserProfile has a OneToOneField to user. On Django 1.2 this meant I could use UserProfile's fields for sorting Users. On Django 1.3 things start to break badly.

I.e.:

class UserProfile(models.Model):
    user = models.OneToOneField(User, editable=False)
    
    first_name = models.CharField(max_length=255, blank=True, verbose_name=_("Firstname"))
    name_prefix = models.CharField(max_length=50, blank=True, verbose_name=_("Lastname prefix"))
    last_name = models.CharField(max_length=255, blank=True, verbose_name=_("Lastname"))

    ...
    
User._meta.ordering = ('userprofile__last_name', 'userprofile__name_prefix', 'userprofile__first_name')

Django 1.2 situation:

>>> from django.contrib.auth.models import User
>>> u = User.objects.all()[0]
>>> User._meta.get_field_by_name('userprofile')
(<RelatedObject: userprofile:userprofile related to user>, None, False, False)
>>> 

Django 1.3 situation:

>>> from django.contrib.auth.models import User
>>> u = User.objects.all()[0]
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  [...]
  File "/home/klaas/dev/online/demo/django/db/models/sql/query.py", line 1238, in setup_joins
    "Choices are: %s" % (name, ", ".join(names)))
FieldError: Cannot resolve keyword 'userprofile' into field. Choices are: ...
>>> User._meta.get_field_by_name('userprofile')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File ".../django/db/models/options.py", line 313, in get_field_by_name
    % (self.object_name, name))
FieldDoesNotExist: User has no field named 'userprofile'

The call to get_field_by_name is what goes wrong in the first place (i.e. it's the method call in setup_joins that's failing), so I've highlighted that above. I assume get_field_by_name() no longer existing for reverse fields might also cause breakage in certain applications, but haven't used it myself in a way that breaks.

I suppose it's not related to poking on User's Meta, and is a problem in general, but I haven't checked that yet.

Change History (3)

comment:1 by Klaas van Schelven, 12 years ago

In fact this is not restricted to Meta's ordering field but is also true for a "manual" call to ordering, i.e. removing ordering from Meta (whether poked or not) and calling:

User.objects.all().order_by("username__lastname")

comment:2 by Luke Plant, 12 years ago

Resolution: worksforme
Status: newclosed

I can't reproduce this on trunk or 1.4. It's possible it was a real bug but was fixed already. Please re-open if you can demonstrate this on trunk. (We wouldn't fix this on the 1.3.X branch, so there is no point me testing there).

comment:3 by Klaas van Schelven, 12 years ago

Turns out this was caused by #18510

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