Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add more stringent M2M tests and fix the bug they exposed

  • Loading branch information...
commit 52edc16086e3c28a78c31975bb4da2f9450590b4 1 parent 5b522cd
@andrewgodwin andrewgodwin authored
View
6 django/db/models/options.py
@@ -9,7 +9,7 @@
from django.db.models.fields.related import ManyToManyRel
from django.db.models.fields import AutoField, FieldDoesNotExist
from django.db.models.fields.proxy import OrderWrt
-from django.db.models.loading import get_models, app_cache_ready, cache
+from django.db.models.loading import app_cache_ready, cache
from django.utils import six
from django.utils.functional import cached_property
from django.utils.encoding import force_text, smart_text, python_2_unicode_compatible
@@ -495,7 +495,7 @@ def _fill_related_objects_cache(self):
cache[obj] = model
# Collect also objects which are in relation to some proxy child/parent of self.
proxy_cache = cache.copy()
- for klass in get_models(include_auto_created=True, only_installed=False):
+ for klass in self.app_cache.get_models(include_auto_created=True, only_installed=False):
if not klass._meta.swapped:
for f in klass._meta.local_fields:
if f.rel and not isinstance(f.rel.to, six.string_types) and f.generate_reverse_relation:
@@ -538,7 +538,7 @@ def _fill_related_many_to_many_cache(self):
cache[obj] = parent
else:
cache[obj] = model
- for klass in get_models(only_installed=False):
+ for klass in self.app_cache.get_models(only_installed=False):
if not klass._meta.swapped:
for f in klass._meta.local_many_to_many:
if (f.rel
View
9 tests/migrations/test_operations.py
@@ -116,7 +116,7 @@ def test_add_field_m2m(self):
"""
project_state = self.set_up_test_model("test_adflmm", second_model=True)
# Test the state alteration
- operation = migrations.AddField("Pony", "stables", models.ManyToManyField("Stable"))
+ operation = migrations.AddField("Pony", "stables", models.ManyToManyField("Stable", related_name="ponies"))
new_state = project_state.clone()
operation.state_forwards("test_adflmm", new_state)
self.assertEqual(len(new_state.models["test_adflmm", "pony"].fields), 4)
@@ -126,6 +126,13 @@ def test_add_field_m2m(self):
operation.database_forwards("test_adflmm", editor, project_state, new_state)
self.assertTableExists("test_adflmm_pony_stables")
self.assertColumnNotExists("test_adflmm_pony", "stables")
+ # Make sure the M2M field actually works
+ app_cache = new_state.render()
+ Pony = app_cache.get_model("test_adflmm", "Pony")
+ p = Pony.objects.create(pink=False, weight=4.55)
+ p.stables.create()
+ self.assertEqual(p.stables.count(), 1)
+ p.stables.all().delete()
# And test reversal
with connection.schema_editor() as editor:
operation.database_backwards("test_adflmm", editor, new_state, project_state)
View
10 tests/schema/models.py
@@ -37,7 +37,7 @@ class BookWithM2M(models.Model):
author = models.ForeignKey(Author)
title = models.CharField(max_length=100, db_index=True)
pub_date = models.DateTimeField()
- tags = models.ManyToManyField("Tag", related_name="books")
+ tags = models.ManyToManyField("TagM2MTest", related_name="books")
class Meta:
app_cache = new_app_cache
@@ -62,6 +62,14 @@ class Meta:
app_cache = new_app_cache
+class TagM2MTest(models.Model):
+ title = models.CharField(max_length=255)
+ slug = models.SlugField(unique=True)
+
+ class Meta:
+ app_cache = new_app_cache
+
+
class TagIndexed(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(unique=True)
View
24 tests/schema/tests.py
@@ -6,7 +6,7 @@
from django.db.models.fields import IntegerField, TextField, CharField, SlugField
from django.db.models.fields.related import ManyToManyField, ForeignKey
from django.db.transaction import atomic
-from .models import Author, AuthorWithM2M, Book, BookWithSlug, BookWithM2M, Tag, TagIndexed, TagUniqueRename, UniqueTest
+from .models import Author, AuthorWithM2M, Book, BookWithSlug, BookWithM2M, Tag, TagIndexed, TagM2MTest, TagUniqueRename, UniqueTest
class SchemaTests(TransactionTestCase):
@@ -20,7 +20,7 @@ class SchemaTests(TransactionTestCase):
available_apps = []
- models = [Author, AuthorWithM2M, Book, BookWithSlug, BookWithM2M, Tag, TagUniqueRename, UniqueTest]
+ models = [Author, AuthorWithM2M, Book, BookWithSlug, BookWithM2M, Tag, TagIndexed, TagM2MTest, TagUniqueRename, UniqueTest]
no_table_strings = ["no such table", "unknown table", "does not exist"]
# Utility functions
@@ -234,7 +234,7 @@ def test_m2m_create(self):
editor.create_model(BookWithM2M)
# Ensure there is now an m2m table there
columns = self.column_classes(BookWithM2M._meta.get_field_by_name("tags")[0].rel.through)
- self.assertEqual(columns['tag_id'][0], "IntegerField")
+ self.assertEqual(columns['tagm2mtest_id'][0], "IntegerField")
def test_m2m(self):
"""
@@ -243,9 +243,9 @@ def test_m2m(self):
# Create the tables
with connection.schema_editor() as editor:
editor.create_model(AuthorWithM2M)
- editor.create_model(Tag)
+ editor.create_model(TagM2MTest)
# Create an M2M field
- new_field = ManyToManyField("schema.Tag", related_name="authors")
+ new_field = ManyToManyField("schema.TagM2MTest", related_name="authors")
new_field.contribute_to_class(AuthorWithM2M, "tags")
try:
# Ensure there's no m2m table there
@@ -258,7 +258,7 @@ def test_m2m(self):
)
# Ensure there is now an m2m table there
columns = self.column_classes(new_field.rel.through)
- self.assertEqual(columns['tag_id'][0], "IntegerField")
+ self.assertEqual(columns['tagm2mtest_id'][0], "IntegerField")
# Remove the M2M table again
with connection.schema_editor() as editor:
editor.remove_field(
@@ -279,17 +279,17 @@ def test_m2m_repoint(self):
with connection.schema_editor() as editor:
editor.create_model(Author)
editor.create_model(BookWithM2M)
- editor.create_model(Tag)
+ editor.create_model(TagM2MTest)
editor.create_model(UniqueTest)
- # Ensure the M2M exists and points to Tag
+ # Ensure the M2M exists and points to TagM2MTest
constraints = connection.introspection.get_constraints(connection.cursor(), BookWithM2M._meta.get_field_by_name("tags")[0].rel.through._meta.db_table)
if connection.features.supports_foreign_keys:
for name, details in constraints.items():
- if details['columns'] == ["tag_id"] and details['foreign_key']:
- self.assertEqual(details['foreign_key'], ('schema_tag', 'id'))
+ if details['columns'] == ["tagm2mtest_id"] and details['foreign_key']:
+ self.assertEqual(details['foreign_key'], ('schema_tagm2mtest', 'id'))
break
else:
- self.fail("No FK constraint for tag_id found")
+ self.fail("No FK constraint for tagm2mtest_id found")
# Repoint the M2M
new_field = ManyToManyField(UniqueTest)
new_field.contribute_to_class(BookWithM2M, "uniques")
@@ -310,7 +310,7 @@ def test_m2m_repoint(self):
self.assertEqual(details['foreign_key'], ('schema_uniquetest', 'id'))
break
else:
- self.fail("No FK constraint for tag_id found")
+ self.fail("No FK constraint for uniquetest_id found")
finally:
# Cleanup model states
BookWithM2M._meta.local_many_to_many.remove(new_field)
Please sign in to comment.
Something went wrong with that request. Please try again.