mirror of
https://github.com/django/django.git
synced 2025-08-08 04:48:27 +00:00
Fixed #23791 -- Corrected object type check for pk__in=qs
When the pk was a relation field, qs.filter(pk__in=qs) didn't work. In addition, fixed Restaurant.objects.filter(place=restaurant_instance), where place is an OneToOneField and the primary key of Restaurant. A big thank you to Josh for review and to Tim for review and cosmetic edits. Thanks to Beauhurst for commissioning the work on this ticket.
This commit is contained in:
parent
736fb1838c
commit
9ed82154bd
5 changed files with 72 additions and 20 deletions
|
@ -277,3 +277,31 @@ def refs_expression(lookup_parts, annotations):
|
|||
if level_n_lookup in annotations and annotations[level_n_lookup]:
|
||||
return annotations[level_n_lookup], lookup_parts[n:]
|
||||
return False, ()
|
||||
|
||||
|
||||
def check_rel_lookup_compatibility(model, target_opts, field):
|
||||
"""
|
||||
Check that self.model is compatible with target_opts. Compatibility
|
||||
is OK if:
|
||||
1) model and opts match (where proxy inheritance is removed)
|
||||
2) model is parent of opts' model or the other way around
|
||||
"""
|
||||
def check(opts):
|
||||
return (
|
||||
model._meta.concrete_model == opts.concrete_model or
|
||||
opts.concrete_model in model._meta.get_parent_list() or
|
||||
model in opts.get_parent_list()
|
||||
)
|
||||
# If the field is a primary key, then doing a query against the field's
|
||||
# model is ok, too. Consider the case:
|
||||
# class Restaurant(models.Model):
|
||||
# place = OnetoOneField(Place, primary_key=True):
|
||||
# Restaurant.objects.filter(pk__in=Restaurant.objects.all()).
|
||||
# If we didn't have the primary key check, then pk__in (== place__in) would
|
||||
# give Place's opts as the target opts, but Restaurant isn't compatible
|
||||
# with that. This logic applies only to primary keys, as when doing __in=qs,
|
||||
# we are going to turn this into __in=qs.values('pk') later on.
|
||||
return (
|
||||
check(target_opts) or
|
||||
(getattr(field, 'primary_key', False) and check(field.model._meta))
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue