0
0
mirror of https://github.com/django/django.git synced 2024-12-01 15:42:04 +01:00
django/tests/model_fields/test_manytomanyfield.py
Tim Graham e5bd585c6e Fixed #28543 -- Prevented ManyToManyField.value_from_object() from being lazy.
Previously, it was a QuerySet which could reevaluate to a new value if the
model's data changes. This is inconsistent with other Field.value_from_object()
methods.

This allows reverting the fix in the admin for refs #27998.
2017-08-31 09:34:44 -04:00

74 lines
2.6 KiB
Python

from django.apps import apps
from django.db import models
from django.test import SimpleTestCase, TestCase
from django.test.utils import isolate_apps
from .models import ManyToMany
class ManyToManyFieldTests(SimpleTestCase):
def test_abstract_model_pending_operations(self):
"""
Many-to-many fields declared on abstract models should not add lazy
relations to resolve relationship declared as string (#24215).
"""
pending_ops_before = list(apps._pending_operations.items())
class AbstractManyToManyModel(models.Model):
fk = models.ForeignKey('missing.FK', models.CASCADE)
class Meta:
abstract = True
self.assertIs(AbstractManyToManyModel._meta.apps, apps)
self.assertEqual(
pending_ops_before,
list(apps._pending_operations.items()),
'Pending lookup added for a many-to-many field on an abstract model'
)
@isolate_apps('model_fields', 'model_fields.tests')
def test_abstract_model_app_relative_foreign_key(self):
class AbstractReferent(models.Model):
reference = models.ManyToManyField('Referred', through='Through')
class Meta:
app_label = 'model_fields'
abstract = True
def assert_app_model_resolved(label):
class Referred(models.Model):
class Meta:
app_label = label
class Through(models.Model):
referred = models.ForeignKey('Referred', on_delete=models.CASCADE)
referent = models.ForeignKey('ConcreteReferent', on_delete=models.CASCADE)
class Meta:
app_label = label
class ConcreteReferent(AbstractReferent):
class Meta:
app_label = label
self.assertEqual(ConcreteReferent._meta.get_field('reference').related_model, Referred)
self.assertEqual(ConcreteReferent.reference.through, Through)
assert_app_model_resolved('model_fields')
assert_app_model_resolved('tests')
class ManyToManyFieldDBTests(TestCase):
def test_value_from_object_instance_without_pk(self):
obj = ManyToMany()
self.assertEqual(obj._meta.get_field('m2m').value_from_object(obj), [])
def test_value_from_object_instance_with_pk(self):
obj = ManyToMany.objects.create()
related_obj = ManyToMany.objects.create()
obj.m2m.add(related_obj)
self.assertEqual(obj._meta.get_field('m2m').value_from_object(obj), [related_obj])