Fixed #21846 -- Made NestedObjects handle related_name with %(app_label)s or %(class)s.
This commit is contained in:
parent
a5ec11c4bb
commit
c3fdeb28ff
|
@ -156,10 +156,14 @@ class NestedObjects(Collector):
|
||||||
def add_edge(self, source, target):
|
def add_edge(self, source, target):
|
||||||
self.edges.setdefault(source, []).append(target)
|
self.edges.setdefault(source, []).append(target)
|
||||||
|
|
||||||
def collect(self, objs, source_attr=None, **kwargs):
|
def collect(self, objs, source=None, source_attr=None, **kwargs):
|
||||||
for obj in objs:
|
for obj in objs:
|
||||||
if source_attr:
|
if source_attr:
|
||||||
self.add_edge(getattr(obj, source_attr), obj)
|
related_name = source_attr % {
|
||||||
|
'class': source._meta.model_name,
|
||||||
|
'app_label': source._meta.app_label,
|
||||||
|
}
|
||||||
|
self.add_edge(getattr(obj, related_name), obj)
|
||||||
else:
|
else:
|
||||||
self.add_edge(None, obj)
|
self.add_edge(None, obj)
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -47,3 +47,18 @@ class Guest(models.Model):
|
||||||
|
|
||||||
class EventGuide(models.Model):
|
class EventGuide(models.Model):
|
||||||
event = models.ForeignKey(Event, on_delete=models.DO_NOTHING)
|
event = models.ForeignKey(Event, on_delete=models.DO_NOTHING)
|
||||||
|
|
||||||
|
|
||||||
|
class Vehicle(models.Model):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class VehicleMixin(Vehicle):
|
||||||
|
vehicle = models.OneToOneField(Vehicle, parent_link=True, related_name='vehicle_%(app_label)s_%(class)s')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
abstract = True
|
||||||
|
|
||||||
|
|
||||||
|
class Car(VehicleMixin):
|
||||||
|
pass
|
||||||
|
|
|
@ -16,7 +16,7 @@ from django.utils.formats import localize
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
|
||||||
from .models import Article, Count, Event, Location, EventGuide
|
from .models import Article, Count, Event, Location, EventGuide, Vehicle, Car
|
||||||
|
|
||||||
|
|
||||||
class NestedObjectsTests(TestCase):
|
class NestedObjectsTests(TestCase):
|
||||||
|
@ -80,6 +80,16 @@ class NestedObjectsTests(TestCase):
|
||||||
# One for Location, one for Guest, and no query for EventGuide
|
# One for Location, one for Guest, and no query for EventGuide
|
||||||
n.collect(objs)
|
n.collect(objs)
|
||||||
|
|
||||||
|
def test_relation_on_abstract(self):
|
||||||
|
"""
|
||||||
|
#21846 -- Check that `NestedObjects.collect()` doesn't trip
|
||||||
|
(AttributeError) on the special notation for relations on abstract
|
||||||
|
models (related_name that contains %(app_label)s and/or %(class)s).
|
||||||
|
"""
|
||||||
|
n = NestedObjects(using=DEFAULT_DB_ALIAS)
|
||||||
|
Car.objects.create()
|
||||||
|
n.collect([Vehicle.objects.first()])
|
||||||
|
|
||||||
|
|
||||||
class UtilTests(SimpleTestCase):
|
class UtilTests(SimpleTestCase):
|
||||||
def test_values_from_lookup_field(self):
|
def test_values_from_lookup_field(self):
|
||||||
|
|
Loading…
Reference in New Issue