Opened 15 years ago
Closed 15 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.