Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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.