Ticket #16055: django_generic_text_id_test.diff
File django_generic_text_id_test.diff, 10.4 KB (added by , 13 years ago) |
---|
-
tests/modeltests/generic_relations/tests.py
3 3 from django.contrib.contenttypes.models import ContentType 4 4 from django.test import TestCase 5 5 6 from models import (TaggedItem, ValuableTaggedItem, Comparison, Animal,7 Vegetable, Mineral)6 from models import (TaggedItem, ValuableTaggedItem, TaggedItemTextID, 7 Comparison, Animal, Vegetable, Mineral) 8 8 9 9 10 10 class GenericRelationsTests(TestCase): 11 11 def test_generic_relations(self): 12 self.base_generic_relations(TaggedItem, 'tags') 13 14 def test_generic_relations_string_id(self): 15 self.base_generic_relations(TaggedItemTextID, 'stringtags') 16 17 def base_generic_relations(self, tag_model, reverse_name): 12 18 # Create the world in 7 lines of code... 13 19 lion = Animal.objects.create(common_name="Lion", latin_name="Panthera leo") 14 20 platypus = Animal.objects.create( … … 18 24 bacon = Vegetable.objects.create(name="Bacon", is_yucky=False) 19 25 quartz = Mineral.objects.create(name="Quartz", hardness=7) 20 26 27 # Helper function 28 def tags(obj): return getattr(obj, reverse_name) 29 21 30 # Objects with declared GenericRelations can be tagged directly -- the 22 31 # API mimics the many-to-many API. 23 bacon.tags.create(tag="fatty") 24 bacon.tags.create(tag="salty") 25 lion.tags.create(tag="yellow") 26 lion.tags.create(tag="hairy") 27 platypus.tags.create(tag="fatty") 28 self.assertQuerysetEqual(lion.tags.all(), [ 29 "<TaggedItem: hairy>", 30 "<TaggedItem: yellow>" 31 ]) 32 self.assertQuerysetEqual(bacon.tags.all(), [ 33 "<TaggedItem: fatty>", 34 "<TaggedItem: salty>" 35 ]) 32 tags(bacon).create(tag="fatty") 33 tags(bacon).create(tag="salty") 34 tags(lion).create(tag="yellow") 35 tags(lion).create(tag="hairy") 36 tags(platypus).create(tag="fatty") 37 self.assertQuerysetEqual(tags(lion).all(), ["hairy", "yellow"], unicode) 38 self.assertQuerysetEqual(tags(bacon).all(), ["fatty", "salty"], unicode) 36 39 37 40 # You can easily access the content object like a foreign key. 38 t = TaggedItem.objects.get(tag="salty")41 t = tag_model.objects.get(tag="salty") 39 42 self.assertEqual(t.content_object, bacon) 40 43 41 44 # Recall that the Mineral class doesn't have an explicit GenericRelation 42 45 # defined. That's OK, because you can create TaggedItems explicitly. 43 tag1 = TaggedItem.objects.create(content_object=quartz, tag="shiny")44 tag2 = TaggedItem.objects.create(content_object=quartz, tag="clearish")46 tag1 = tag_model.objects.create(content_object=quartz, tag="shiny") 47 tag2 = tag_model.objects.create(content_object=quartz, tag="clearish") 45 48 46 49 # However, excluding GenericRelations means your lookups have to be a 47 50 # bit more explicit. 48 51 ctype = ContentType.objects.get_for_model(quartz) 49 q = TaggedItem.objects.filter(52 q = tag_model.objects.filter( 50 53 content_type__pk=ctype.id, object_id=quartz.id 51 54 ) 52 self.assertQuerysetEqual(q, [ 53 "<TaggedItem: clearish>", 54 "<TaggedItem: shiny>" 55 ]) 55 self.assertQuerysetEqual(q, ["clearish", "shiny"], unicode) 56 56 57 57 # You can set a generic foreign key in the way you'd expect. 58 58 tag1.content_object = platypus 59 59 tag1.save() 60 self.assertQuerysetEqual(platypus.tags.all(), [ 61 "<TaggedItem: fatty>", 62 "<TaggedItem: shiny>" 63 ]) 64 q = TaggedItem.objects.filter( 60 self.assertQuerysetEqual(tags(platypus).all(), ["fatty", "shiny"], unicode) 61 q = tag_model.objects.filter( 65 62 content_type__pk=ctype.id, object_id=quartz.id 66 63 ) 67 self.assertQuerysetEqual(q, [" <TaggedItem: clearish>"])64 self.assertQuerysetEqual(q, ["clearish"], unicode) 68 65 69 66 # Queries across generic relations respect the content types. Even 70 67 # though there are two TaggedItems with a tag of "fatty", this query … … 73 70 "<Animal: Lion>", 74 71 "<Animal: Platypus>" 75 72 ]) 76 self.assertQuerysetEqual(Animal.objects.filter(tags__tag='fatty'), [ 73 74 print Animal.objects.filter(**{reverse_name + '__tag': 'fatty'}).query 75 self.assertQuerysetEqual(Animal.objects.filter(**{reverse_name + '__tag': 'fatty'}), [ 77 76 "<Animal: Platypus>" 78 77 ]) 79 self.assertQuerysetEqual(Animal.objects.exclude(tags__tag='fatty'), [ 78 print Animal.objects.exclude(**{reverse_name + '__tag': 'fatty'}).query 79 self.assertQuerysetEqual(Animal.objects.exclude(**{reverse_name + '__tag': 'fatty'}), [ 80 80 "<Animal: Lion>" 81 81 ]) 82 82 … … 84 84 # objects are deleted when the source object is deleted. 85 85 # Original list of tags: 86 86 comp_func = lambda obj: ( 87 obj.tag, obj.content_type.model_class(), obj.object_id87 obj.tag, obj.content_type.model_class(), unicode(obj.object_id) 88 88 ) 89 89 90 self.assertQuerysetEqual( TaggedItem.objects.all(), [91 (u'clearish', Mineral, quartz.pk),92 (u'fatty', Animal, platypus.pk),93 (u'fatty', Vegetable, bacon.pk),94 (u'hairy', Animal, lion.pk),95 (u'salty', Vegetable, bacon.pk),96 (u'shiny', Animal, platypus.pk),97 (u'yellow', Animal, lion.pk)90 self.assertQuerysetEqual(tag_model.objects.all(), [ 91 (u'clearish', Mineral, unicode(quartz.pk)), 92 (u'fatty', Animal, unicode(platypus.pk)), 93 (u'fatty', Vegetable, unicode(bacon.pk)), 94 (u'hairy', Animal, unicode(lion.pk)), 95 (u'salty', Vegetable, unicode(bacon.pk)), 96 (u'shiny', Animal, unicode(platypus.pk)), 97 (u'yellow', Animal, unicode(lion.pk)) 98 98 ], 99 99 comp_func 100 100 ) 101 101 lion.delete() 102 self.assertQuerysetEqual( TaggedItem.objects.all(), [103 (u'clearish', Mineral, quartz.pk),104 (u'fatty', Animal, platypus.pk),105 (u'fatty', Vegetable, bacon.pk),106 (u'salty', Vegetable, bacon.pk),107 (u'shiny', Animal, platypus.pk)102 self.assertQuerysetEqual(tag_model.objects.all(), [ 103 (u'clearish', Mineral, unicode(quartz.pk)), 104 (u'fatty', Animal, unicode(platypus.pk)), 105 (u'fatty', Vegetable, unicode(bacon.pk)), 106 (u'salty', Vegetable, unicode(bacon.pk)), 107 (u'shiny', Animal, unicode(platypus.pk)) 108 108 ], 109 109 comp_func 110 110 ) … … 113 113 # remain after deletion of the source object. 114 114 quartz_pk = quartz.pk 115 115 quartz.delete() 116 self.assertQuerysetEqual( TaggedItem.objects.all(), [117 (u'clearish', Mineral, quartz_pk),118 (u'fatty', Animal, platypus.pk),119 (u'fatty', Vegetable, bacon.pk),120 (u'salty', Vegetable, bacon.pk),121 (u'shiny', Animal, platypus.pk)116 self.assertQuerysetEqual(tag_model.objects.all(), [ 117 (u'clearish', Mineral, unicode(quartz_pk)), 118 (u'fatty', Animal, unicode(platypus.pk)), 119 (u'fatty', Vegetable, unicode(bacon.pk)), 120 (u'salty', Vegetable, unicode(bacon.pk)), 121 (u'shiny', Animal, unicode(platypus.pk)) 122 122 ], 123 123 comp_func 124 124 ) 125 125 # If you delete a tag, the objects using the tag are unaffected 126 126 # (other than losing a tag) 127 tag = TaggedItem.objects.order_by("id")[0]127 tag = tag_model.objects.order_by("id")[0] 128 128 tag.delete() 129 self.assertQuerysetEqual( bacon.tags.all(), ["<TaggedItem: salty>"])130 self.assertQuerysetEqual( TaggedItem.objects.all(), [131 (u'clearish', Mineral, quartz_pk),132 (u'fatty', Animal, platypus.pk),133 (u'salty', Vegetable, bacon.pk),134 (u'shiny', Animal, platypus.pk)129 self.assertQuerysetEqual(tags(bacon).all(), ["salty"], unicode) 130 self.assertQuerysetEqual(tag_model.objects.all(), [ 131 (u'clearish', Mineral, unicode(quartz_pk)), 132 (u'fatty', Animal, unicode(platypus.pk)), 133 (u'salty', Vegetable, unicode(bacon.pk)), 134 (u'shiny', Animal, unicode(platypus.pk)) 135 135 ], 136 136 comp_func 137 137 ) 138 TaggedItem.objects.filter(tag='fatty').delete()138 tag_model.objects.filter(tag='fatty').delete() 139 139 ctype = ContentType.objects.get_for_model(lion) 140 self.assertQuerysetEqual(Animal.objects.filter( tags__content_type=ctype), [140 self.assertQuerysetEqual(Animal.objects.filter(**{reverse_name + '__content_type': ctype}), [ 141 141 "<Animal: Platypus>" 142 142 ]) 143 143 -
tests/modeltests/generic_relations/models.py
31 31 class ValuableTaggedItem(TaggedItem): 32 32 value = models.PositiveIntegerField() 33 33 34 class TaggedItemTextID(models.Model): 35 tag = models.SlugField() 36 content_type = models.ForeignKey(ContentType) 37 object_id = models.TextField() 38 39 content_object = generic.GenericForeignKey() 40 41 class Meta: 42 ordering = ["tag", "content_type__name"] 43 44 def __unicode__(self): 45 return self.tag 46 34 47 class Comparison(models.Model): 35 48 """ 36 49 A model that tests having multiple GenericForeignKeys … … 54 67 latin_name = models.CharField(max_length=150) 55 68 56 69 tags = generic.GenericRelation(TaggedItem) 70 stringtags = generic.GenericRelation(TaggedItemTextID) 57 71 comparisons = generic.GenericRelation(Comparison, 58 72 object_id_field="object_id1", 59 73 content_type_field="content_type1") … … 66 80 is_yucky = models.BooleanField(default=True) 67 81 68 82 tags = generic.GenericRelation(TaggedItem) 83 stringtags = generic.GenericRelation(TaggedItemTextID) 69 84 70 85 def __unicode__(self): 71 86 return self.name