Opened 14 years ago
Closed 14 years ago
#15164 closed (worksforme)
Filtering queryset via ForeignKey to legacy model with OneToOneField as primary doesn't evaluate primary key
Reported by: | Sam Thompson | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.2 |
Severity: | 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
If you have one model with a OneToOneField as primary_key and also specify a db_column and another model with a foreign key to the first, like this:
class UserProfile(models.Model): user = models.OneToOneField(User, primary_key=True, db_column='uid') email = models.CharField(max_length=255, unique=True) username = models.CharField(unique=True, max_length=150) class Meta: db_table = u'legacy_user' class OtherModel(models.Model): user = models.ForeignKey('my_app.UserProfile', db_column='uid') some_data = models.IntegerField() another_model = models.ForeignKey('other_app.AnotherModel', db_column='related') class Meta: db_table = u'legacy_other_model'
When you perform this queryset you get weird SQL:
my_user = UserProfile.objects.get(username='foo') count = OtherModel.objects.filter(user=my_user).count() SELECT COUNT(*) FROM `legacy_other_model` WHERE `legacy_other_model`.`uid` = None
But if you explicitly filter on the object's pk, it works:
count = OtherModel.objects.filter(user=my_user.pk).count() SELECT COUNT(*) FROM `legacy_other_model` WHERE `legacy_other_model`.`uid` = 12345
This doesn't seem to be the expected behavior, looking at: http://docs.djangoproject.com/en/dev/topics/db/queries/#queries-over-related-objects
Note:
See TracTickets
for help on using tickets.
Using the provided models and queries, I can't replicate this problem in either trunk or 1.2, on SQLite, MySQL, or Postgres. The first query (by my_user) generates the correct SQL for me in every case.
Thanks for the report. Please reopen if you can demonstrate the problem as a patch against Django's own test suite with a failing test case, or in a brand-new simplest-case project running on Django trunk.