问题
I made a typo in my code recently and noticed that I got the same behavior, so I was wondering what the difference between single and double underscores are in django queries.
>>> underscore = MyModel.objects.filter(foreign_key_id=var)
>>> double_underscore = MyModel.objects.filter(foreign_key__id=var)
>>> underscore == double_underscore
False
>>> list(underscore) == list(double_underscore)
True
I'm not sure what equality method is being used to compare the querysets, but when I convert to python lists I find exactly the same elements contained within. Does anyone have some insight into what's going on here?
回答1:
Those two fields just happen to both exist.
foreign_key_id
is an automatically created column on the MyModel
object, whereas foreign_key__id
is the ID on the foreign key table itself.
These values would both be the same..
MyModel1.foreign_key_id == 5 # this is stored on the model
# and does not require a lookup.
MyModel1.foreign_key.id == 5 # this is stored on the target table
# and requires a DB hit.
回答2:
foreign_key_id
is a (hidden) field name of MyModel
, foreign_key__id
is a reference to a field on whatever model the foreign_key
field references. In other words, it is a specific detail of foreign key fields.
回答3:
From my observations, Django is smart enough to not do a join with the ForeignKey if only filtering or fetching foreign_key__id
. You can test this with:
>>> print(MyModel.objects.filter(foreign_key_id=var).query)
>>> print(MyModel.objects.filter(foreign_key__id=var).query)
Since underscore
and double_underscore
are separate objects in memory, I believe this is why underscore == double_underscore
returns False.
来源:https://stackoverflow.com/questions/14945242/django-query-single-underscore-behaving-like-double-underscore