summaryrefslogtreecommitdiff
path: root/tests/model_meta
diff options
context:
space:
mode:
authorDaniel Pyrathon <pirosb3@gmail.com>2014-06-19 16:03:36 +0200
committerTim Graham <timograham@gmail.com>2014-06-19 12:56:36 -0400
commitd862fae5bbfb52ab7aeaad5a59b3d8b27b30c8f9 (patch)
treedbde27942cc7e120fab234096f24c2e1804a60f0 /tests/model_meta
parent01399fa0aaa817281c77bbb4b7d82c6c8487c916 (diff)
downloaddjango-d862fae5bbfb52ab7aeaad5a59b3d8b27b30c8f9.tar.gz
Refs #12663 -- Added tests for methods in db.models.options.
Thanks Russell Keith-Magee and Tim Graham for reviews.
Diffstat (limited to 'tests/model_meta')
-rw-r--r--tests/model_meta/__init__.py0
-rw-r--r--tests/model_meta/models.py120
-rw-r--r--tests/model_meta/test.py656
3 files changed, 776 insertions, 0 deletions
diff --git a/tests/model_meta/__init__.py b/tests/model_meta/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/model_meta/__init__.py
diff --git a/tests/model_meta/models.py b/tests/model_meta/models.py
new file mode 100644
index 0000000000..ab9713dc38
--- /dev/null
+++ b/tests/model_meta/models.py
@@ -0,0 +1,120 @@
+from django.db import models
+
+from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
+from django.contrib.contenttypes.models import ContentType
+
+
+class Relation(models.Model):
+ pass
+
+
+class AbstractPerson(models.Model):
+ # DATA fields
+ data_abstract = models.CharField(max_length=10)
+ fk_abstract = models.ForeignKey(Relation, related_name='fk_abstract_rel')
+
+ # M2M fields
+ m2m_abstract = models.ManyToManyField(Relation, related_name='m2m_abstract_rel')
+ friends_abstract = models.ManyToManyField('self', related_name='friends_abstract', symmetrical=True)
+ following_abstract = models.ManyToManyField('self', related_name='followers_abstract', symmetrical=False)
+
+ # VIRTUAL fields
+ data_not_concrete_abstract = models.ForeignObject(
+ Relation,
+ from_fields=['abstract_non_concrete_id'],
+ to_fields=['id'],
+ related_name='fo_abstract_rel',
+ )
+
+ # GFK fields
+ content_type_abstract = models.ForeignKey(ContentType, related_name='+')
+ object_id_abstract = models.PositiveIntegerField()
+ content_object_abstract = GenericForeignKey('content_type_abstract', 'object_id_abstract')
+
+ # GR fields
+ generic_relation_abstract = GenericRelation(Relation)
+
+ class Meta:
+ abstract = True
+
+
+class BasePerson(AbstractPerson):
+ # DATA fields
+ data_base = models.CharField(max_length=10)
+ fk_base = models.ForeignKey(Relation, related_name='fk_base_rel')
+
+ # M2M fields
+ m2m_base = models.ManyToManyField(Relation, related_name='m2m_base_rel')
+ friends_base = models.ManyToManyField('self', related_name='friends_base', symmetrical=True)
+ following_base = models.ManyToManyField('self', related_name='followers_base', symmetrical=False)
+
+ # VIRTUAL fields
+ data_not_concrete_base = models.ForeignObject(
+ Relation,
+ from_fields=['base_non_concrete_id'],
+ to_fields=['id'],
+ related_name='fo_base_rel',
+ )
+
+ # GFK fields
+ content_type_base = models.ForeignKey(ContentType, related_name='+')
+ object_id_base = models.PositiveIntegerField()
+ content_object_base = GenericForeignKey('content_type_base', 'object_id_base')
+
+ # GR fields
+ generic_relation_base = GenericRelation(Relation)
+
+
+class Person(BasePerson):
+ # DATA fields
+ data_inherited = models.CharField(max_length=10)
+ fk_inherited = models.ForeignKey(Relation, related_name='fk_concrete_rel')
+
+ # M2M Fields
+ m2m_inherited = models.ManyToManyField(Relation, related_name='m2m_concrete_rel')
+ friends_inherited = models.ManyToManyField('self', related_name='friends_concrete', symmetrical=True)
+ following_inherited = models.ManyToManyField('self', related_name='followers_concrete', symmetrical=False)
+
+ # VIRTUAL fields
+ data_not_concrete_inherited = models.ForeignObject(
+ Relation,
+ from_fields=['model_non_concrete_id'],
+ to_fields=['id'],
+ related_name='fo_concrete_rel',
+ )
+
+ # GFK fields
+ content_type_concrete = models.ForeignKey(ContentType, related_name='+')
+ object_id_concrete = models.PositiveIntegerField()
+ content_object_concrete = GenericForeignKey('content_type_concrete', 'object_id_concrete')
+
+ # GR fields
+ generic_relation_concrete = GenericRelation(Relation)
+
+
+class ProxyPerson(Person):
+ class Meta:
+ proxy = True
+
+
+class Relating(models.Model):
+
+ # ForeignKey to BasePerson
+ baseperson = models.ForeignKey(BasePerson, related_name='relating_baseperson')
+ baseperson_hidden = models.ForeignKey(BasePerson, related_name='+')
+
+ # ForeignKey to Person
+ person = models.ForeignKey(Person, related_name='relating_person')
+ person_hidden = models.ForeignKey(Person, related_name='+')
+
+ # ForeignKey to ProxyPerson
+ proxyperson = models.ForeignKey(ProxyPerson, related_name='relating_proxyperson')
+ proxyperson_hidden = models.ForeignKey(ProxyPerson, related_name='+')
+
+ # ManyToManyField to BasePerson
+ basepeople = models.ManyToManyField(BasePerson, related_name='relating_basepeople')
+ basepeople_hidden = models.ManyToManyField(BasePerson, related_name='+')
+
+ # ManyToManyField to Person
+ people = models.ManyToManyField(Person, related_name='relating_people')
+ people_hidden = models.ManyToManyField(Person, related_name='+')
diff --git a/tests/model_meta/test.py b/tests/model_meta/test.py
new file mode 100644
index 0000000000..89a5575665
--- /dev/null
+++ b/tests/model_meta/test.py
@@ -0,0 +1,656 @@
+from django import test
+
+from django.db.models.fields import related, CharField, Field
+from django.contrib.contenttypes.fields import GenericForeignKey
+
+from .models import (
+ AbstractPerson, BasePerson, Person, Relating, Relation
+)
+
+TEST_RESULTS = {
+ 'fields': {
+ Person: [
+ 'id',
+ 'data_abstract',
+ 'fk_abstract_id',
+ 'data_not_concrete_abstract',
+ 'content_type_abstract_id',
+ 'object_id_abstract',
+ 'data_base',
+ 'fk_base_id',
+ 'data_not_concrete_base',
+ 'content_type_base_id',
+ 'object_id_base',
+ 'baseperson_ptr_id',
+ 'data_inherited',
+ 'fk_inherited_id',
+ 'data_not_concrete_inherited',
+ 'content_type_concrete_id',
+ 'object_id_concrete',
+ ],
+ BasePerson: [
+ 'id',
+ 'data_abstract',
+ 'fk_abstract_id',
+ 'data_not_concrete_abstract',
+ 'content_type_abstract_id',
+ 'object_id_abstract',
+ 'data_base',
+ 'fk_base_id',
+ 'data_not_concrete_base',
+ 'content_type_base_id',
+ 'object_id_base',
+ ],
+ AbstractPerson: [
+ 'data_abstract',
+ 'fk_abstract_id',
+ 'data_not_concrete_abstract',
+ 'content_type_abstract_id',
+ 'object_id_abstract',
+ ],
+ Relating: [
+ 'id',
+ 'baseperson_id',
+ 'baseperson_hidden_id',
+ 'person_id',
+ 'person_hidden_id',
+ 'proxyperson_id',
+ 'proxyperson_hidden_id',
+ ],
+ },
+ 'local_fields': {
+ Person: [
+ 'baseperson_ptr_id',
+ 'data_inherited',
+ 'fk_inherited_id',
+ 'data_not_concrete_inherited',
+ 'content_type_concrete_id',
+ 'object_id_concrete',
+ ],
+ BasePerson: [
+ 'id',
+ 'data_abstract',
+ 'fk_abstract_id',
+ 'data_not_concrete_abstract',
+ 'content_type_abstract_id',
+ 'object_id_abstract',
+ 'data_base',
+ 'fk_base_id',
+ 'data_not_concrete_base',
+ 'content_type_base_id',
+ 'object_id_base',
+ ],
+ AbstractPerson: [
+ 'data_abstract',
+ 'fk_abstract_id',
+ 'data_not_concrete_abstract',
+ 'content_type_abstract_id',
+ 'object_id_abstract',
+ ],
+ Relating: [
+ 'id',
+ 'baseperson_id',
+ 'baseperson_hidden_id',
+ 'person_id',
+ 'person_hidden_id',
+ 'proxyperson_id',
+ 'proxyperson_hidden_id',
+ ],
+ },
+ 'local_concrete_fields': {
+ Person: [
+ 'baseperson_ptr_id',
+ 'data_inherited',
+ 'fk_inherited_id',
+ 'content_type_concrete_id',
+ 'object_id_concrete',
+ ],
+ BasePerson: [
+ 'id',
+ 'data_abstract',
+ 'fk_abstract_id',
+ 'content_type_abstract_id',
+ 'object_id_abstract',
+ 'data_base',
+ 'fk_base_id',
+ 'content_type_base_id',
+ 'object_id_base',
+ ],
+ AbstractPerson: [
+ 'data_abstract',
+ 'fk_abstract_id',
+ 'content_type_abstract_id',
+ 'object_id_abstract',
+ ],
+ Relating: [
+ 'id',
+ 'baseperson_id',
+ 'baseperson_hidden_id',
+ 'person_id',
+ 'person_hidden_id',
+ 'proxyperson_id',
+ 'proxyperson_hidden_id',
+ ],
+ },
+ 'many_to_many': {
+ Person: [
+ 'm2m_abstract',
+ 'friends_abstract',
+ 'following_abstract',
+ 'm2m_base',
+ 'friends_base',
+ 'following_base',
+ 'm2m_inherited',
+ 'friends_inherited',
+ 'following_inherited',
+ ],
+ BasePerson: [
+ 'm2m_abstract',
+ 'friends_abstract',
+ 'following_abstract',
+ 'm2m_base',
+ 'friends_base',
+ 'following_base',
+ ],
+ AbstractPerson: [
+ 'm2m_abstract',
+ 'friends_abstract',
+ 'following_abstract',
+ ],
+ Relating: [
+ 'basepeople',
+ 'basepeople_hidden',
+ 'people',
+ 'people_hidden',
+ ],
+ },
+ 'many_to_many_with_model': {
+ Person: [
+ BasePerson,
+ BasePerson,
+ BasePerson,
+ BasePerson,
+ BasePerson,
+ BasePerson,
+ None,
+ None,
+ None,
+ ],
+ BasePerson: [
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ ],
+ AbstractPerson: [
+ None,
+ None,
+ None,
+ ],
+ Relating: [
+ None,
+ None,
+ None,
+ None,
+ ],
+ },
+ 'get_all_related_objects_with_model': {
+ Person: (
+ ('relating_baseperson', BasePerson),
+ ('relating_person', None),
+ ),
+ BasePerson: (
+ ('person', None),
+ ('relating_baseperson', None),
+ ),
+ Relation: (
+ ('fk_abstract_rel', None),
+ ('fo_abstract_rel', None),
+ ('fk_base_rel', None),
+ ('fo_base_rel', None),
+ ('fk_concrete_rel', None),
+ ('fo_concrete_rel', None),
+ ),
+ },
+ 'get_all_related_objects_with_model_local': {
+ Person: (
+ ('relating_person', None),
+ ),
+ BasePerson: (
+ ('person', None),
+ ('relating_baseperson', None)
+ ),
+ Relation: (
+ ('fk_abstract_rel', None),
+ ('fo_abstract_rel', None),
+ ('fk_base_rel', None),
+ ('fo_base_rel', None),
+ ('fk_concrete_rel', None),
+ ('fo_concrete_rel', None),
+ ),
+ },
+ 'get_all_related_objects_with_model_hidden': {
+ BasePerson: (
+ ('model_meta:baseperson_friends_base', None),
+ ('model_meta:baseperson_friends_base', None),
+ ('model_meta:baseperson_m2m_base', None),
+ ('model_meta:baseperson_following_base', None),
+ ('model_meta:baseperson_following_base', None),
+ ('model_meta:baseperson_m2m_abstract', None),
+ ('model_meta:baseperson_friends_abstract', None),
+ ('model_meta:baseperson_friends_abstract', None),
+ ('model_meta:baseperson_following_abstract', None),
+ ('model_meta:baseperson_following_abstract', None),
+ ('model_meta:person', None),
+ ('model_meta:relating_basepeople', None),
+ ('model_meta:relating_basepeople_hidden', None),
+ ('model_meta:relating', None),
+ ('model_meta:relating', None),
+ ),
+ Person: (
+ ('model_meta:baseperson_friends_base', BasePerson),
+ ('model_meta:baseperson_friends_base', BasePerson),
+ ('model_meta:baseperson_m2m_base', BasePerson),
+ ('model_meta:baseperson_following_base', BasePerson),
+ ('model_meta:baseperson_following_base', BasePerson),
+ ('model_meta:baseperson_m2m_abstract', BasePerson),
+ ('model_meta:baseperson_friends_abstract', BasePerson),
+ ('model_meta:baseperson_friends_abstract', BasePerson),
+ ('model_meta:baseperson_following_abstract', BasePerson),
+ ('model_meta:baseperson_following_abstract', BasePerson),
+ ('model_meta:relating_basepeople', BasePerson),
+ ('model_meta:relating_basepeople_hidden', BasePerson),
+ ('model_meta:relating', BasePerson),
+ ('model_meta:relating', BasePerson),
+ ('model_meta:person_m2m_inherited', None),
+ ('model_meta:person_friends_inherited', None),
+ ('model_meta:person_friends_inherited', None),
+ ('model_meta:person_following_inherited', None),
+ ('model_meta:person_following_inherited', None),
+ ('model_meta:relating_people', None),
+ ('model_meta:relating_people_hidden', None),
+ ('model_meta:relating', None),
+ ('model_meta:relating', None),
+ ),
+ Relation: (
+ ('model_meta:baseperson_m2m_base', None),
+ ('model_meta:baseperson_m2m_abstract', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:person_m2m_inherited', None),
+ ('model_meta:person', None),
+ ('model_meta:person', None),
+ ('model_meta:person', None),
+ ('model_meta:person', None),
+ ('model_meta:person', None),
+ ('model_meta:proxyperson', None),
+ ('model_meta:proxyperson', None),
+ ('model_meta:proxyperson', None),
+ ),
+ },
+ 'get_all_related_objects_with_model_hidden_local': {
+ BasePerson: (
+ ('model_meta:baseperson_friends_base', None),
+ ('model_meta:baseperson_friends_base', None),
+ ('model_meta:baseperson_m2m_base', None),
+ ('model_meta:baseperson_following_base', None),
+ ('model_meta:baseperson_following_base', None),
+ ('model_meta:baseperson_m2m_abstract', None),
+ ('model_meta:baseperson_friends_abstract', None),
+ ('model_meta:baseperson_friends_abstract', None),
+ ('model_meta:baseperson_following_abstract', None),
+ ('model_meta:baseperson_following_abstract', None),
+ ('model_meta:person', None),
+ ('model_meta:relating_basepeople', None),
+ ('model_meta:relating_basepeople_hidden', None),
+ ('model_meta:relating', None),
+ ('model_meta:relating', None),
+ ),
+ Person: (
+ ('model_meta:person_m2m_inherited', None),
+ ('model_meta:person_friends_inherited', None),
+ ('model_meta:person_friends_inherited', None),
+ ('model_meta:person_following_inherited', None),
+ ('model_meta:person_following_inherited', None),
+ ('model_meta:relating_people', None),
+ ('model_meta:relating_people_hidden', None),
+ ('model_meta:relating', None),
+ ('model_meta:relating', None),
+ ),
+ Relation: (
+ ('model_meta:baseperson_m2m_base', None),
+ ('model_meta:baseperson_m2m_abstract', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:person_m2m_inherited', None),
+ ('model_meta:person', None),
+ ('model_meta:person', None),
+ ('model_meta:person', None),
+ ('model_meta:person', None),
+ ('model_meta:person', None),
+ ('model_meta:proxyperson', None),
+ ('model_meta:proxyperson', None),
+ ('model_meta:proxyperson', None),
+ ),
+ },
+ 'get_all_related_objects_with_model_proxy': {
+ BasePerson: (
+ ('person', None),
+ ('relating_baseperson', None),
+ ),
+ Person: (
+ ('relating_baseperson', BasePerson),
+ ('relating_person', None), ('relating_proxyperson', None),
+ ),
+ Relation: (
+ ('fk_abstract_rel', None), ('fo_abstract_rel', None),
+ ('fk_base_rel', None), ('fo_base_rel', None),
+ ('fk_concrete_rel', None), ('fo_concrete_rel', None),
+ ),
+ },
+ 'get_all_related_objects_with_model_proxy_hidden': {
+ BasePerson: (
+ ('model_meta:baseperson_friends_base', None),
+ ('model_meta:baseperson_friends_base', None),
+ ('model_meta:baseperson_m2m_base', None),
+ ('model_meta:baseperson_following_base', None),
+ ('model_meta:baseperson_following_base', None),
+ ('model_meta:baseperson_m2m_abstract', None),
+ ('model_meta:baseperson_friends_abstract', None),
+ ('model_meta:baseperson_friends_abstract', None),
+ ('model_meta:baseperson_following_abstract', None),
+ ('model_meta:baseperson_following_abstract', None),
+ ('model_meta:person', None),
+ ('model_meta:relating_basepeople', None),
+ ('model_meta:relating_basepeople_hidden', None),
+ ('model_meta:relating', None),
+ ('model_meta:relating', None),
+ ),
+ Person: (
+ ('model_meta:baseperson_friends_base', BasePerson),
+ ('model_meta:baseperson_friends_base', BasePerson),
+ ('model_meta:baseperson_m2m_base', BasePerson),
+ ('model_meta:baseperson_following_base', BasePerson),
+ ('model_meta:baseperson_following_base', BasePerson),
+ ('model_meta:baseperson_m2m_abstract', BasePerson),
+ ('model_meta:baseperson_friends_abstract', BasePerson),
+ ('model_meta:baseperson_friends_abstract', BasePerson),
+ ('model_meta:baseperson_following_abstract', BasePerson),
+ ('model_meta:baseperson_following_abstract', BasePerson),
+ ('model_meta:relating_basepeople', BasePerson),
+ ('model_meta:relating_basepeople_hidden', BasePerson),
+ ('model_meta:relating', BasePerson),
+ ('model_meta:relating', BasePerson),
+ ('model_meta:person_m2m_inherited', None),
+ ('model_meta:person_friends_inherited', None),
+ ('model_meta:person_friends_inherited', None),
+ ('model_meta:person_following_inherited', None),
+ ('model_meta:person_following_inherited', None),
+ ('model_meta:relating_people', None),
+ ('model_meta:relating_people_hidden', None),
+ ('model_meta:relating', None),
+ ('model_meta:relating', None),
+ ('model_meta:relating', None),
+ ('model_meta:relating', None),
+ ),
+ Relation: (
+ ('model_meta:baseperson_m2m_base', None),
+ ('model_meta:baseperson_m2m_abstract', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:baseperson', None),
+ ('model_meta:person_m2m_inherited', None),
+ ('model_meta:person', None),
+ ('model_meta:person', None),
+ ('model_meta:person', None),
+ ('model_meta:person', None),
+ ('model_meta:person', None),
+ ('model_meta:proxyperson', None),
+ ('model_meta:proxyperson', None),
+ ('model_meta:proxyperson', None),
+ ),
+ },
+ 'get_all_related_many_to_many_with_model': {
+ BasePerson: (
+ ('friends_abstract_rel_+', None),
+ ('followers_abstract', None),
+ ('friends_base_rel_+', None),
+ ('followers_base', None),
+ ('relating_basepeople', None),
+ ('+', None),
+ ),
+ Person: (
+ ('friends_abstract_rel_+', BasePerson),
+ ('followers_abstract', BasePerson),
+ ('friends_base_rel_+', BasePerson),
+ ('followers_base', BasePerson),
+ ('relating_basepeople', BasePerson),
+ ('+', BasePerson),
+ ('friends_inherited_rel_+', None),
+ ('followers_concrete', None),
+ ('relating_people', None),
+ ('+', None),
+ ),
+ Relation: (
+ ('m2m_abstract_rel', None),
+ ('m2m_base_rel', None),
+ ('m2m_concrete_rel', None),
+ ),
+ },
+ 'get_all_related_many_to_many_local': {
+ BasePerson: [
+ 'friends_abstract_rel_+',
+ 'followers_abstract',
+ 'friends_base_rel_+',
+ 'followers_base',
+ 'relating_basepeople',
+ '+',
+ ],
+ Person: [
+ 'friends_inherited_rel_+',
+ 'followers_concrete',
+ 'relating_people',
+ '+',
+ ],
+ Relation: [
+ 'm2m_abstract_rel',
+ 'm2m_base_rel',
+ 'm2m_concrete_rel',
+ ],
+ },
+ 'virtual_fields': {
+ AbstractPerson: [
+ 'generic_relation_abstract',
+ 'content_object_abstract',
+ ],
+ BasePerson: [
+ 'generic_relation_base',
+ 'content_object_base',
+ 'generic_relation_abstract',
+ 'content_object_abstract',
+ ],
+ Person: [
+ 'content_object_concrete',
+ 'generic_relation_concrete',
+ 'generic_relation_base',
+ 'content_object_base',
+ 'generic_relation_abstract',
+ 'content_object_abstract',
+ ],
+ },
+}
+
+
+class OptionsBaseTests(test.TestCase):
+
+ def _map_rq_names(self, res):
+ return tuple([(o.field.related_query_name(), m) for o, m in res])
+
+ def _map_names(self, res):
+ return tuple([(f.name, m) for f, m in res])
+
+
+class DataTests(OptionsBaseTests):
+
+ def test_fields(self):
+ for model, expected_result in TEST_RESULTS['fields'].items():
+ fields = model._meta.fields
+ self.assertEqual([f.attname for f in fields], expected_result)
+
+ def test_local_fields(self):
+ is_data_field = lambda f: isinstance(f, Field) and not isinstance(f, related.ManyToManyField)
+
+ for model, expected_result in TEST_RESULTS['local_fields'].items():
+ fields = model._meta.local_fields
+ self.assertEqual([f.attname for f in fields], expected_result)
+ self.assertTrue(all([f.model is model for f in fields]))
+ self.assertTrue(all([is_data_field(f) for f in fields]))
+
+ def test_local_concrete_fields(self):
+ for model, expected_result in TEST_RESULTS['local_concrete_fields'].items():
+ fields = model._meta.local_concrete_fields
+ self.assertEqual([f.attname for f in fields], expected_result)
+ self.assertTrue(all([f.column is not None for f in fields]))
+
+
+class M2MTests(OptionsBaseTests):
+
+ def test_many_to_many(self):
+ for model, expected_result in TEST_RESULTS['many_to_many'].items():
+ fields = model._meta.many_to_many
+ self.assertEqual([f.attname for f in fields], expected_result)
+ self.assertTrue(all([isinstance(f.rel, related.ManyToManyRel) for f in fields]))
+
+ def test_many_to_many_with_model(self):
+ for model, expected_result in TEST_RESULTS['many_to_many_with_model'].items():
+ models = [model for field, model in model._meta.get_m2m_with_model()]
+ self.assertEqual(models, expected_result)
+
+
+class RelatedObjectsTests(OptionsBaseTests):
+ def setUp(self):
+ self.key_name = lambda r: r[0]
+
+ def test_related_objects(self):
+ result_key = 'get_all_related_objects_with_model'
+ for model, expected in TEST_RESULTS[result_key].items():
+ objects = model._meta.get_all_related_objects_with_model()
+ self.assertEqual(self._map_rq_names(objects), expected)
+
+ def test_related_objects_local(self):
+ result_key = 'get_all_related_objects_with_model_local'
+ for model, expected in TEST_RESULTS[result_key].items():
+ objects = model._meta.get_all_related_objects_with_model(local_only=True)
+ self.assertEqual(self._map_rq_names(objects), expected)
+
+ def test_related_objects_include_hidden(self):
+ result_key = 'get_all_related_objects_with_model_hidden'
+ for model, expected in TEST_RESULTS[result_key].items():
+ objects = model._meta.get_all_related_objects_with_model(include_hidden=True)
+ self.assertEqual(
+ sorted(self._map_names(objects), key=self.key_name),
+ sorted(expected, key=self.key_name)
+ )
+
+ def test_related_objects_include_hidden_local_only(self):
+ result_key = 'get_all_related_objects_with_model_hidden_local'
+ for model, expected in TEST_RESULTS[result_key].items():
+ objects = model._meta.get_all_related_objects_with_model(
+ include_hidden=True, local_only=True)
+ self.assertEqual(
+ sorted(self._map_names(objects), key=self.key_name),
+ sorted(expected, key=self.key_name)
+ )
+
+ def test_related_objects_proxy(self):
+ result_key = 'get_all_related_objects_with_model_proxy'
+ for model, expected in TEST_RESULTS[result_key].items():
+ objects = model._meta.get_all_related_objects_with_model(
+ include_proxy_eq=True)
+ self.assertEqual(self._map_rq_names(objects), expected)
+
+ def test_related_objects_proxy_hidden(self):
+ result_key = 'get_all_related_objects_with_model_proxy_hidden'
+ for model, expected in TEST_RESULTS[result_key].items():
+ objects = model._meta.get_all_related_objects_with_model(
+ include_proxy_eq=True, include_hidden=True)
+ self.assertEqual(
+ sorted(self._map_names(objects), key=self.key_name),
+ sorted(expected, key=self.key_name)
+ )
+
+
+class RelatedM2MTests(OptionsBaseTests):
+
+ def test_related_m2m_with_model(self):
+ result_key = 'get_all_related_many_to_many_with_model'
+ for model, expected in TEST_RESULTS[result_key].items():
+ objects = model._meta.get_all_related_m2m_objects_with_model()
+ self.assertEqual(self._map_rq_names(objects), expected)
+
+ def test_related_m2m_local_only(self):
+ result_key = 'get_all_related_many_to_many_local'
+ for model, expected in TEST_RESULTS[result_key].items():
+ objects = model._meta.get_all_related_many_to_many_objects(local_only=True)
+ self.assertEqual([o.field.related_query_name() for o in objects], expected)
+
+ def test_related_m2m_asymmetrical(self):
+ m2m = Person._meta.many_to_many
+ self.assertTrue('following_base' in [f.attname for f in m2m])
+ related_m2m = Person._meta.get_all_related_many_to_many_objects()
+ self.assertTrue('followers_base' in [o.field.related_query_name() for o in related_m2m])
+
+ def test_related_m2m_symmetrical(self):
+ m2m = Person._meta.many_to_many
+ self.assertTrue('friends_base' in [f.attname for f in m2m])
+ related_m2m = Person._meta.get_all_related_many_to_many_objects()
+ self.assertIn('friends_inherited_rel_+', [o.field.related_query_name() for o in related_m2m])
+
+
+class VirtualFieldsTests(OptionsBaseTests):
+
+ def test_virtual_fields(self):
+ for model, expected_names in TEST_RESULTS['virtual_fields'].items():
+ objects = model._meta.virtual_fields
+ self.assertEqual(sorted([f.name for f in objects]), sorted(expected_names))
+
+
+class GetFieldByNameTests(OptionsBaseTests):
+
+ def test_get_data_field(self):
+ field_info = Person._meta.get_field_by_name('data_abstract')
+ self.assertEqual(field_info[1:], (BasePerson, True, False))
+ self.assertIsInstance(field_info[0], CharField)
+
+ def test_get_m2m_field(self):
+ field_info = Person._meta.get_field_by_name('m2m_base')
+ self.assertEqual(field_info[1:], (BasePerson, True, True))
+ self.assertIsInstance(field_info[0], related.ManyToManyField)
+
+ def test_get_related_object(self):
+ field_info = Person._meta.get_field_by_name('relating_baseperson')
+ self.assertEqual(field_info[1:], (BasePerson, False, False))
+ self.assertIsInstance(field_info[0], related.RelatedObject)
+
+ def test_get_related_m2m(self):
+ field_info = Person._meta.get_field_by_name('relating_people')
+ self.assertEqual(field_info[1:], (None, False, True))
+ self.assertIsInstance(field_info[0], related.RelatedObject)
+
+ def test_get_virtual_field(self):
+ field_info = Person._meta.get_field_by_name('content_object_base')
+ self.assertEqual(field_info[1:], (None, True, False))
+ self.assertIsInstance(field_info[0], GenericForeignKey)