Fix reverse relation support for ___ filter operator
parent
137139f2bb
commit
b0657ef9c7
|
|
@ -1,6 +1,13 @@
|
|||
Changelog
|
||||
==========
|
||||
|
||||
Version 0.8.1 (2015-12-29)
|
||||
--------------------------
|
||||
|
||||
* Fixed support for reverse relations for ``relname___field`` when the field starts with an ``_`` character.
|
||||
Otherwise, the query will be interpreted as subclass lookup (``ClassName___field``).
|
||||
|
||||
|
||||
Version 0.8 (2015-12-28)
|
||||
------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -4,11 +4,25 @@
|
|||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import django
|
||||
from django.db import models
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db.models import Q, FieldDoesNotExist
|
||||
|
||||
from django.db.models.fields.related import RelatedField # Django 1.8
|
||||
from django.db.models.fields.related import RelatedField
|
||||
if django.VERSION < (1, 6):
|
||||
# There was no common base class in Django 1.5, mention all variants here.
|
||||
from django.db.models.fields.related import RelatedObject, ManyToOneRel, ManyToManyRel
|
||||
REL_FIELD_CLASSES = (RelatedField, RelatedObject, ManyToOneRel, ManyToManyRel) # Leaving GenericRel out.
|
||||
elif django.VERSION < (1, 8):
|
||||
# As of Django 1.6 there is a ForeignObjectRel.
|
||||
from django.db.models.fields.related import ForeignObjectRel, RelatedObject
|
||||
REL_FIELD_CLASSES = (RelatedField, ForeignObjectRel, RelatedObject)
|
||||
else:
|
||||
# As of Django 1.8 the base class serves everything. RelatedObject is gone.
|
||||
from django.db.models.fields.related import ForeignObjectRel
|
||||
REL_FIELD_CLASSES = (RelatedField, ForeignObjectRel)
|
||||
|
||||
|
||||
from functools import reduce
|
||||
|
||||
|
|
@ -154,9 +168,13 @@ def translate_polymorphic_field_path(queryset_model, field_path):
|
|||
# Test whether it's actually a regular relation__ _fieldname (the field starting with an _)
|
||||
# so no tripple ClassName___field was intended.
|
||||
try:
|
||||
# rel = (field_object, model, direct, m2m)
|
||||
if django.VERSION >= (1, 8):
|
||||
# This also retreives M2M relations now (including reverse foreign key relations)
|
||||
field = queryset_model._meta.get_field(classname)
|
||||
if isinstance(field, RelatedField):
|
||||
else:
|
||||
field = queryset_model._meta.get_field_by_name(classname)[0]
|
||||
|
||||
if isinstance(field, REL_FIELD_CLASSES):
|
||||
# Can also test whether the field exists in the related object to avoid ambiguity between
|
||||
# class names and field names, but that never happens when your class names are in CamelCase.
|
||||
return field_path # No exception raised, field does exist.
|
||||
|
|
|
|||
|
|
@ -159,7 +159,8 @@ class ModelUnderRelParent(PolymorphicModel):
|
|||
|
||||
|
||||
class ModelUnderRelChild(PolymorphicModel):
|
||||
parent = models.ForeignKey(ModelUnderRelParent)
|
||||
parent = models.ForeignKey(ModelUnderRelParent, related_name='children')
|
||||
_private2 = models.CharField(max_length=10)
|
||||
|
||||
|
||||
class MyManagerQuerySet(PolymorphicQuerySet):
|
||||
|
|
@ -734,12 +735,20 @@ class PolymorphicTests(TestCase):
|
|||
|
||||
def test_polymorphic___filter_field(self):
|
||||
p = ModelUnderRelParent.objects.create(_private=True, field1='AA')
|
||||
ModelUnderRelChild.objects.create(parent=p)
|
||||
ModelUnderRelChild.objects.create(parent=p, _private2=True)
|
||||
|
||||
# The "___" filter should also parse to "parent" -> "_private" as fallback.
|
||||
objects = ModelUnderRelChild.objects.filter(parent___private=True)
|
||||
self.assertEqual(len(objects), 1)
|
||||
|
||||
def test_polymorphic___filter_reverse_field(self):
|
||||
p = ModelUnderRelParent.objects.create(_private=True, field1='BB')
|
||||
ModelUnderRelChild.objects.create(parent=p, _private2=True)
|
||||
|
||||
# Also test for reverse relations
|
||||
objects = ModelUnderRelParent.objects.filter(children___private2=True)
|
||||
self.assertEqual(len(objects), 1)
|
||||
|
||||
def test_delete(self):
|
||||
self.create_model2abcd()
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue