Refs #18586 -- Split up model_inheritance.ModelInheritanceTest
This commit is contained in:
parent
49d034fff2
commit
2cd19f3738
|
@ -49,9 +49,16 @@ class ModelInheritanceTests(TestCase):
|
||||||
# doesn't exist as a model).
|
# doesn't exist as a model).
|
||||||
self.assertRaises(AttributeError, lambda: CommonInfo.objects.all())
|
self.assertRaises(AttributeError, lambda: CommonInfo.objects.all())
|
||||||
|
|
||||||
def test_multiple_table(self):
|
def test_reverse_relation_for_different_hierarchy_tree(self):
|
||||||
post = Post.objects.create(title="Lorem Ipsum")
|
# Even though p.supplier for a Place 'p' (a parent of a Supplier), a
|
||||||
|
# Restaurant object cannot access that reverse relation, since it's not
|
||||||
|
# part of the Place-Supplier Hierarchy.
|
||||||
|
self.assertQuerysetEqual(Place.objects.filter(supplier__name="foo"), [])
|
||||||
|
self.assertRaises(FieldError, Restaurant.objects.filter, supplier__name="foo")
|
||||||
|
|
||||||
|
def test_model_with_distinct_accessors(self):
|
||||||
# The Post model has distinct accessors for the Comment and Link models.
|
# The Post model has distinct accessors for the Comment and Link models.
|
||||||
|
post = Post.objects.create(title="Lorem Ipsum")
|
||||||
post.attached_comment_set.create(content="Save $ on V1agr@", is_spam=True)
|
post.attached_comment_set.create(content="Save $ on V1agr@", is_spam=True)
|
||||||
post.attached_link_set.create(
|
post.attached_link_set.create(
|
||||||
content="The Web framework for perfections with deadlines.",
|
content="The Web framework for perfections with deadlines.",
|
||||||
|
@ -64,47 +71,7 @@ class ModelInheritanceTests(TestCase):
|
||||||
AttributeError, getattr, post, "attached_%(class)s_set"
|
AttributeError, getattr, post, "attached_%(class)s_set"
|
||||||
)
|
)
|
||||||
|
|
||||||
# The Place/Restaurant/ItalianRestaurant models all exist as
|
def test_meta_fields_and_ordering(self):
|
||||||
# independent models. However, the subclasses also have transparent
|
|
||||||
# access to the fields of their ancestors.
|
|
||||||
# Create a couple of Places.
|
|
||||||
Place.objects.create(name="Master Shakes", address="666 W. Jersey")
|
|
||||||
Place.objects.create(name="Ace Hardware", address="1013 N. Ashland")
|
|
||||||
|
|
||||||
# Test constructor for Restaurant.
|
|
||||||
r = Restaurant.objects.create(
|
|
||||||
name="Demon Dogs",
|
|
||||||
address="944 W. Fullerton",
|
|
||||||
serves_hot_dogs=True,
|
|
||||||
serves_pizza=False,
|
|
||||||
rating=2
|
|
||||||
)
|
|
||||||
# Test the constructor for ItalianRestaurant.
|
|
||||||
c = Chef.objects.create(name="Albert")
|
|
||||||
ir = ItalianRestaurant.objects.create(
|
|
||||||
name="Ristorante Miron",
|
|
||||||
address="1234 W. Ash",
|
|
||||||
serves_hot_dogs=False,
|
|
||||||
serves_pizza=False,
|
|
||||||
serves_gnocchi=True,
|
|
||||||
rating=4,
|
|
||||||
chef=c
|
|
||||||
)
|
|
||||||
self.assertQuerysetEqual(
|
|
||||||
ItalianRestaurant.objects.filter(address="1234 W. Ash"), [
|
|
||||||
"Ristorante Miron",
|
|
||||||
],
|
|
||||||
attrgetter("name")
|
|
||||||
)
|
|
||||||
ir.address = "1234 W. Elm"
|
|
||||||
ir.save()
|
|
||||||
self.assertQuerysetEqual(
|
|
||||||
ItalianRestaurant.objects.filter(address="1234 W. Elm"), [
|
|
||||||
"Ristorante Miron",
|
|
||||||
],
|
|
||||||
attrgetter("name")
|
|
||||||
)
|
|
||||||
|
|
||||||
# Make sure Restaurant and ItalianRestaurant have the right fields in
|
# Make sure Restaurant and ItalianRestaurant have the right fields in
|
||||||
# the right order.
|
# the right order.
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
@ -119,14 +86,91 @@ class ModelInheritanceTests(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(Restaurant._meta.ordering, ["-rating"])
|
self.assertEqual(Restaurant._meta.ordering, ["-rating"])
|
||||||
|
|
||||||
# Even though p.supplier for a Place 'p' (a parent of a Supplier), a
|
def test_custompk_m2m(self):
|
||||||
# Restaurant object cannot access that reverse relation, since it's not
|
b = Base.objects.create()
|
||||||
# part of the Place-Supplier Hierarchy.
|
b.titles.add(Title.objects.create(title="foof"))
|
||||||
self.assertQuerysetEqual(Place.objects.filter(supplier__name="foo"), [])
|
s = SubBase.objects.create(sub_id=b.id)
|
||||||
self.assertRaises(
|
b = Base.objects.get(pk=s.id)
|
||||||
FieldError, Restaurant.objects.filter, supplier__name="foo"
|
self.assertNotEqual(b.pk, s.pk)
|
||||||
|
# Low-level test for related_val
|
||||||
|
self.assertEqual(s.titles.related_val, (s.id,))
|
||||||
|
# Higher level test for correct query values (title foof not
|
||||||
|
# accidentally found).
|
||||||
|
self.assertQuerysetEqual(s.titles.all(), [])
|
||||||
|
|
||||||
|
def test_update_parent_filtering(self):
|
||||||
|
"""
|
||||||
|
Test that updating a field of a model subclass doesn't issue an UPDATE
|
||||||
|
query constrained by an inner query.
|
||||||
|
Refs #10399
|
||||||
|
"""
|
||||||
|
supplier = Supplier.objects.create(
|
||||||
|
name='Central market',
|
||||||
|
address='610 some street',
|
||||||
|
)
|
||||||
|
# Capture the expected query in a database agnostic way
|
||||||
|
with CaptureQueriesContext(connection) as captured_queries:
|
||||||
|
Place.objects.filter(pk=supplier.pk).update(name=supplier.name)
|
||||||
|
expected_sql = captured_queries[0]['sql']
|
||||||
|
# Capture the queries executed when a subclassed model instance is saved.
|
||||||
|
with CaptureQueriesContext(connection) as captured_queries:
|
||||||
|
supplier.save(update_fields=('name',))
|
||||||
|
for query in captured_queries:
|
||||||
|
sql = query['sql']
|
||||||
|
if 'UPDATE' in sql:
|
||||||
|
self.assertEqual(expected_sql, sql)
|
||||||
|
|
||||||
|
def test_eq(self):
|
||||||
|
# Equality doesn't transfer in multitable inheritance.
|
||||||
|
self.assertNotEqual(Place(id=1), Restaurant(id=1))
|
||||||
|
self.assertNotEqual(Restaurant(id=1), Place(id=1))
|
||||||
|
|
||||||
|
def test_mixin_init(self):
|
||||||
|
m = MixinModel()
|
||||||
|
self.assertEqual(m.other_attr, 1)
|
||||||
|
|
||||||
|
|
||||||
|
class ModelInheritanceDataTests(TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpTestData(cls):
|
||||||
|
cls.restaurant = Restaurant.objects.create(
|
||||||
|
name="Demon Dogs",
|
||||||
|
address="944 W. Fullerton",
|
||||||
|
serves_hot_dogs=True,
|
||||||
|
serves_pizza=False,
|
||||||
|
rating=2,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
chef = Chef.objects.create(name="Albert")
|
||||||
|
cls.italian_restaurant = ItalianRestaurant.objects.create(
|
||||||
|
name="Ristorante Miron",
|
||||||
|
address="1234 W. Ash",
|
||||||
|
serves_hot_dogs=False,
|
||||||
|
serves_pizza=False,
|
||||||
|
serves_gnocchi=True,
|
||||||
|
rating=4,
|
||||||
|
chef=chef,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_filter_inherited_model(self):
|
||||||
|
self.assertQuerysetEqual(
|
||||||
|
ItalianRestaurant.objects.filter(address="1234 W. Ash"), [
|
||||||
|
"Ristorante Miron",
|
||||||
|
],
|
||||||
|
attrgetter("name")
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_update_inherited_model(self):
|
||||||
|
self.italian_restaurant.address = "1234 W. Elm"
|
||||||
|
self.italian_restaurant.save()
|
||||||
|
self.assertQuerysetEqual(
|
||||||
|
ItalianRestaurant.objects.filter(address="1234 W. Elm"), [
|
||||||
|
"Ristorante Miron",
|
||||||
|
],
|
||||||
|
attrgetter("name")
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_parent_fields_available_for_filtering_in_child_model(self):
|
||||||
# Parent fields can be used directly in filters on the child model.
|
# Parent fields can be used directly in filters on the child model.
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Restaurant.objects.filter(name="Demon Dogs"), [
|
Restaurant.objects.filter(name="Demon Dogs"), [
|
||||||
|
@ -135,21 +179,24 @@ class ModelInheritanceTests(TestCase):
|
||||||
attrgetter("name")
|
attrgetter("name")
|
||||||
)
|
)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
ItalianRestaurant.objects.filter(address="1234 W. Elm"), [
|
ItalianRestaurant.objects.filter(address="1234 W. Ash"), [
|
||||||
"Ristorante Miron",
|
"Ristorante Miron",
|
||||||
],
|
],
|
||||||
attrgetter("name")
|
attrgetter("name")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_filter_on_parent_returns_object_of_parent_type(self):
|
||||||
# Filters against the parent model return objects of the parent's type.
|
# Filters against the parent model return objects of the parent's type.
|
||||||
p = Place.objects.get(name="Demon Dogs")
|
p = Place.objects.get(name="Demon Dogs")
|
||||||
self.assertIs(type(p), Place)
|
self.assertIs(type(p), Place)
|
||||||
|
|
||||||
|
def test_parent_child_one_to_one_link(self):
|
||||||
# Since the parent and child are linked by an automatically created
|
# Since the parent and child are linked by an automatically created
|
||||||
# OneToOneField, you can get from the parent to the child by using the
|
# OneToOneField, you can get from the parent to the child by using the
|
||||||
# child's name.
|
# child's name.
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
p.restaurant, Restaurant.objects.get(name="Demon Dogs")
|
Place.objects.get(name="Demon Dogs").restaurant,
|
||||||
|
Restaurant.objects.get(name="Demon Dogs")
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
Place.objects.get(name="Ristorante Miron").restaurant.italianrestaurant,
|
Place.objects.get(name="Ristorante Miron").restaurant.italianrestaurant,
|
||||||
|
@ -160,29 +207,35 @@ class ModelInheritanceTests(TestCase):
|
||||||
ItalianRestaurant.objects.get(name="Ristorante Miron")
|
ItalianRestaurant.objects.get(name="Ristorante Miron")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_parent_child_one_to_one_link_on_nonrelated_objects(self):
|
||||||
# This won't work because the Demon Dogs restaurant is not an Italian
|
# This won't work because the Demon Dogs restaurant is not an Italian
|
||||||
# restaurant.
|
# restaurant.
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
ItalianRestaurant.DoesNotExist,
|
ItalianRestaurant.DoesNotExist,
|
||||||
lambda: p.restaurant.italianrestaurant
|
lambda: Place.objects.get(name="Demon Dogs").restaurant.italianrestaurant
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_inherited_does_not_exist_exception(self):
|
||||||
# An ItalianRestaurant which does not exist is also a Place which does
|
# An ItalianRestaurant which does not exist is also a Place which does
|
||||||
# not exist.
|
# not exist.
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
Place.DoesNotExist,
|
Place.DoesNotExist,
|
||||||
ItalianRestaurant.objects.get, name="The Noodle Void"
|
ItalianRestaurant.objects.get, name="The Noodle Void"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_inherited_multiple_objects_returned_exception(self):
|
||||||
# MultipleObjectsReturned is also inherited.
|
# MultipleObjectsReturned is also inherited.
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
Place.MultipleObjectsReturned,
|
Place.MultipleObjectsReturned,
|
||||||
Restaurant.objects.get, id__lt=12321
|
Restaurant.objects.get, id__lt=12321
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_related_objects_for_inherited_models(self):
|
||||||
# Related objects work just as they normally do.
|
# Related objects work just as they normally do.
|
||||||
s1 = Supplier.objects.create(name="Joe's Chickens", address="123 Sesame St")
|
s1 = Supplier.objects.create(name="Joe's Chickens", address="123 Sesame St")
|
||||||
s1.customers = [r, ir]
|
s1.customers = [self.restaurant, self.italian_restaurant]
|
||||||
s2 = Supplier.objects.create(name="Luigi's Pasta", address="456 Sesame St")
|
s2 = Supplier.objects.create(name="Luigi's Pasta", address="456 Sesame St")
|
||||||
s2.customers = [ir]
|
s2.customers = [self.italian_restaurant]
|
||||||
|
|
||||||
# This won't work because the Place we select is not a Restaurant (it's
|
# This won't work because the Place we select is not a Restaurant (it's
|
||||||
# a Supplier).
|
# a Supplier).
|
||||||
|
@ -193,7 +246,7 @@ class ModelInheritanceTests(TestCase):
|
||||||
|
|
||||||
self.assertEqual(p.supplier, s1)
|
self.assertEqual(p.supplier, s1)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
ir.provider.order_by("-name"), [
|
self.italian_restaurant.provider.order_by("-name"), [
|
||||||
"Luigi's Pasta",
|
"Luigi's Pasta",
|
||||||
"Joe's Chickens"
|
"Joe's Chickens"
|
||||||
],
|
],
|
||||||
|
@ -217,7 +270,7 @@ class ModelInheritanceTests(TestCase):
|
||||||
name="Main St", address="111 Main St", main_site=s1
|
name="Main St", address="111 Main St", main_site=s1
|
||||||
)
|
)
|
||||||
ParkingLot.objects.create(
|
ParkingLot.objects.create(
|
||||||
name="Well Lit", address="124 Sesame St", main_site=ir
|
name="Well Lit", address="124 Sesame St", main_site=self.italian_restaurant
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
@ -225,6 +278,7 @@ class ModelInheritanceTests(TestCase):
|
||||||
"Ristorante Miron"
|
"Ristorante Miron"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_update_works_on_parent_and_child_models_at_once(self):
|
||||||
# The update() command can update fields in parent and child classes at
|
# The update() command can update fields in parent and child classes at
|
||||||
# once (although it executed multiple SQL queries to do so).
|
# once (although it executed multiple SQL queries to do so).
|
||||||
rows = Restaurant.objects.filter(
|
rows = Restaurant.objects.filter(
|
||||||
|
@ -234,18 +288,20 @@ class ModelInheritanceTests(TestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(rows, 1)
|
self.assertEqual(rows, 1)
|
||||||
|
|
||||||
r1 = Restaurant.objects.get(pk=r.pk)
|
r1 = Restaurant.objects.get(pk=self.restaurant.pk)
|
||||||
self.assertFalse(r1.serves_hot_dogs)
|
self.assertFalse(r1.serves_hot_dogs)
|
||||||
self.assertEqual(r1.name, "Demon Puppies")
|
self.assertEqual(r1.name, "Demon Puppies")
|
||||||
|
|
||||||
|
def test_values_works_on_parent_model_fields(self):
|
||||||
# The values() command also works on fields from parent models.
|
# The values() command also works on fields from parent models.
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
ItalianRestaurant.objects.values("name", "rating"), [
|
ItalianRestaurant.objects.values("name", "rating"), [
|
||||||
{"rating": 4, "name": "Ristorante Miron"}
|
{"rating": 4, "name": "Ristorante Miron"},
|
||||||
],
|
],
|
||||||
lambda o: o
|
lambda o: o
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_select_related_works_on_parent_model_fields(self):
|
||||||
# select_related works with fields from the parent object as if they
|
# select_related works with fields from the parent object as if they
|
||||||
# were a normal part of the model.
|
# were a normal part of the model.
|
||||||
self.assertNumQueries(
|
self.assertNumQueries(
|
||||||
|
@ -260,22 +316,6 @@ class ModelInheritanceTests(TestCase):
|
||||||
#23370 - Should be able to defer child fields when using
|
#23370 - Should be able to defer child fields when using
|
||||||
select_related() from parent to child.
|
select_related() from parent to child.
|
||||||
"""
|
"""
|
||||||
Restaurant.objects.create(
|
|
||||||
name="Demon Dogs",
|
|
||||||
address="944 W. Fullerton",
|
|
||||||
serves_hot_dogs=True,
|
|
||||||
serves_pizza=False,
|
|
||||||
rating=2,
|
|
||||||
)
|
|
||||||
ItalianRestaurant.objects.create(
|
|
||||||
name="Ristorante Miron",
|
|
||||||
address="1234 W. Ash",
|
|
||||||
serves_hot_dogs=False,
|
|
||||||
serves_pizza=False,
|
|
||||||
serves_gnocchi=True,
|
|
||||||
rating=4,
|
|
||||||
)
|
|
||||||
|
|
||||||
qs = (Restaurant.objects
|
qs = (Restaurant.objects
|
||||||
.select_related("italianrestaurant")
|
.select_related("italianrestaurant")
|
||||||
.defer("italianrestaurant__serves_gnocchi")
|
.defer("italianrestaurant__serves_gnocchi")
|
||||||
|
@ -292,91 +332,53 @@ class ModelInheritanceTests(TestCase):
|
||||||
self.assertEqual(qs[1].italianrestaurant.name, 'Ristorante Miron')
|
self.assertEqual(qs[1].italianrestaurant.name, 'Ristorante Miron')
|
||||||
self.assertEqual(qs[1].italianrestaurant.rating, 4)
|
self.assertEqual(qs[1].italianrestaurant.rating, 4)
|
||||||
|
|
||||||
def test_mixin_init(self):
|
|
||||||
m = MixinModel()
|
|
||||||
self.assertEqual(m.other_attr, 1)
|
|
||||||
|
|
||||||
def test_update_query_counts(self):
|
def test_update_query_counts(self):
|
||||||
"""
|
"""
|
||||||
Test that update queries do not generate non-necessary queries.
|
Test that update queries do not generate non-necessary queries.
|
||||||
Refs #18304.
|
Refs #18304.
|
||||||
"""
|
"""
|
||||||
c = Chef.objects.create(name="Albert")
|
|
||||||
ir = ItalianRestaurant.objects.create(
|
|
||||||
name="Ristorante Miron",
|
|
||||||
address="1234 W. Ash",
|
|
||||||
serves_hot_dogs=False,
|
|
||||||
serves_pizza=False,
|
|
||||||
serves_gnocchi=True,
|
|
||||||
rating=4,
|
|
||||||
chef=c
|
|
||||||
)
|
|
||||||
with self.assertNumQueries(3):
|
with self.assertNumQueries(3):
|
||||||
ir.save()
|
self.italian_restaurant.save()
|
||||||
|
|
||||||
def test_update_parent_filtering(self):
|
def test_filter_inherited_on_null(self):
|
||||||
"""
|
# Refs #12567
|
||||||
Test that updating a field of a model subclass doesn't issue an UPDATE
|
Supplier.objects.create(
|
||||||
query constrained by an inner query.
|
name="Central market",
|
||||||
Refs #10399
|
address="610 some street",
|
||||||
"""
|
|
||||||
supplier = Supplier.objects.create(
|
|
||||||
name='Central market',
|
|
||||||
address='610 some street'
|
|
||||||
)
|
|
||||||
# Capture the expected query in a database agnostic way
|
|
||||||
with CaptureQueriesContext(connection) as captured_queries:
|
|
||||||
Place.objects.filter(pk=supplier.pk).update(name=supplier.name)
|
|
||||||
expected_sql = captured_queries[0]['sql']
|
|
||||||
# Capture the queries executed when a subclassed model instance is saved.
|
|
||||||
with CaptureQueriesContext(connection) as captured_queries:
|
|
||||||
supplier.save(update_fields=('name',))
|
|
||||||
for query in captured_queries:
|
|
||||||
sql = query['sql']
|
|
||||||
if 'UPDATE' in sql:
|
|
||||||
self.assertEqual(expected_sql, sql)
|
|
||||||
|
|
||||||
def test_eq(self):
|
|
||||||
# Equality doesn't transfer in multitable inheritance.
|
|
||||||
self.assertNotEqual(Place(id=1), Restaurant(id=1))
|
|
||||||
self.assertNotEqual(Restaurant(id=1), Place(id=1))
|
|
||||||
|
|
||||||
def test_ticket_12567(self):
|
|
||||||
r = Restaurant.objects.create(name='n1', address='a1')
|
|
||||||
s = Supplier.objects.create(name='s1', address='a2')
|
|
||||||
self.assertQuerysetEqual(
|
|
||||||
Place.objects.filter(supplier__isnull=False),
|
|
||||||
[Place.objects.get(pk=s.pk)],
|
|
||||||
lambda x: x
|
|
||||||
)
|
)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Place.objects.filter(supplier__isnull=True),
|
Place.objects.filter(supplier__isnull=False), [
|
||||||
[Place.objects.get(pk=r.pk)],
|
"Central market",
|
||||||
lambda x: x
|
],
|
||||||
|
attrgetter("name")
|
||||||
)
|
)
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
Place.objects.exclude(supplier__isnull=False),
|
Place.objects.filter(supplier__isnull=True).order_by("name"), [
|
||||||
[Place.objects.get(pk=r.pk)],
|
"Demon Dogs",
|
||||||
lambda x: x
|
"Ristorante Miron",
|
||||||
)
|
],
|
||||||
self.assertQuerysetEqual(
|
attrgetter("name")
|
||||||
Place.objects.exclude(supplier__isnull=True),
|
|
||||||
[Place.objects.get(pk=s.pk)],
|
|
||||||
lambda x: x
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_custompk_m2m(self):
|
def test_exclude_inherited_on_null(self):
|
||||||
b = Base.objects.create()
|
# Refs #12567
|
||||||
b.titles.add(Title.objects.create(title="foof"))
|
Supplier.objects.create(
|
||||||
s = SubBase.objects.create(sub_id=b.id)
|
name="Central market",
|
||||||
b = Base.objects.get(pk=s.id)
|
address="610 some street",
|
||||||
self.assertNotEqual(b.pk, s.pk)
|
)
|
||||||
# Low-level test for related_val
|
|
||||||
self.assertEqual(s.titles.related_val, (s.id,))
|
|
||||||
# Higher level test for correct query values (title foof not
|
|
||||||
# accidentally found).
|
|
||||||
self.assertQuerysetEqual(
|
self.assertQuerysetEqual(
|
||||||
s.titles.all(), [])
|
Place.objects.exclude(supplier__isnull=False).order_by("name"), [
|
||||||
|
"Demon Dogs",
|
||||||
|
"Ristorante Miron",
|
||||||
|
],
|
||||||
|
attrgetter("name")
|
||||||
|
)
|
||||||
|
self.assertQuerysetEqual(
|
||||||
|
Place.objects.exclude(supplier__isnull=True), [
|
||||||
|
"Central market",
|
||||||
|
],
|
||||||
|
attrgetter("name")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class InheritanceSameModelNameTests(TransactionTestCase):
|
class InheritanceSameModelNameTests(TransactionTestCase):
|
||||||
|
|
Loading…
Reference in New Issue