mirror of
				https://github.com/django/django.git
				synced 2025-10-28 16:16:12 +00:00 
			
		
		
		
	Refs #12663 -- Added tests for methods in db.models.options.
Thanks Russell Keith-Magee and Tim Graham for reviews.
This commit is contained in:
		
				
					committed by
					
						 Tim Graham
						Tim Graham
					
				
			
			
				
	
			
			
			
						parent
						
							01399fa0aa
						
					
				
				
					commit
					d862fae5bb
				
			
							
								
								
									
										1
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								AUTHORS
									
									
									
									
									
								
							| @@ -517,6 +517,7 @@ answer newbie questions, and generally made Django that much better: | |||||||
|     Matthias Pronk <django@masida.nl> |     Matthias Pronk <django@masida.nl> | ||||||
|     Jyrki Pulliainen <jyrki.pulliainen@gmail.com> |     Jyrki Pulliainen <jyrki.pulliainen@gmail.com> | ||||||
|     Thejaswi Puthraya <thejaswi.puthraya@gmail.com> |     Thejaswi Puthraya <thejaswi.puthraya@gmail.com> | ||||||
|  |     Daniel Pyrathon <pirosb3@gmail.com> | ||||||
|     Johann Queuniet <johann.queuniet@adh.naellia.eu> |     Johann Queuniet <johann.queuniet@adh.naellia.eu> | ||||||
|     Ram Rachum <ram@rachum.com> |     Ram Rachum <ram@rachum.com> | ||||||
|     Jan Rademaker |     Jan Rademaker | ||||||
|   | |||||||
							
								
								
									
										0
									
								
								tests/model_meta/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								tests/model_meta/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										120
									
								
								tests/model_meta/models.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								tests/model_meta/models.py
									
									
									
									
									
										Normal file
									
								
							| @@ -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='+') | ||||||
							
								
								
									
										656
									
								
								tests/model_meta/test.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										656
									
								
								tests/model_meta/test.py
									
									
									
									
									
										Normal file
									
								
							| @@ -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) | ||||||
		Reference in New Issue
	
	Block a user