From 0b84b7ef3eb7fb69e2ef135da4bae41aacd1ab38 Mon Sep 17 00:00:00 2001 From: David Hatch Date: Wed, 6 Jul 2011 00:02:21 -0400 Subject: [PATCH] added tests and documentation for representing a reverse GenericRelation --- tastypie/fields.py | 4 +++ tests/related_resource/api/resources.py | 2 +- tests/related_resource/models.py | 2 +- tests/related_resource/tests.py | 41 ++++++++++++++++++++++++- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/tastypie/fields.py b/tastypie/fields.py index 7903d0823..b86e0072c 100644 --- a/tastypie/fields.py +++ b/tastypie/fields.py @@ -697,6 +697,10 @@ class ToManyField(RelatedField): Note that the ``hydrate`` portions of this field are quite different than any other field. ``hydrate_m2m`` actually handles the data and relations. This is due to the way Django implements M2M relationships. + + Can be used to represent a ``GenericRelation`` + (reverse of ``GenericForeignKey``). Simply set ``to`` to the resource + which represents the other end of the relation. """ is_m2m = True help_text = 'Many related resources. Can be either a list of URIs or list of individually nested resource data.' diff --git a/tests/related_resource/api/resources.py b/tests/related_resource/api/resources.py index 63414f9b5..a955df762 100644 --- a/tests/related_resource/api/resources.py +++ b/tests/related_resource/api/resources.py @@ -24,7 +24,7 @@ class Meta: class CategoryResource(ModelResource): parent = fields.ToOneField('self', 'parent', null=True) - + tags = fields.ToManyField('related_resource.api.resources.GenericTagResource', attribute="tags", null=True, blank=True) class Meta: resource_name = 'category' queryset = Category.objects.all() diff --git a/tests/related_resource/models.py b/tests/related_resource/models.py index 9d333714d..a6bd6aea9 100644 --- a/tests/related_resource/models.py +++ b/tests/related_resource/models.py @@ -5,7 +5,7 @@ class Category(models.Model): parent = models.ForeignKey('self', null=True) name = models.CharField(max_length=32) - + tags = generic.GenericRelation('related_resource.GenericTag') def __unicode__(self): return u"%s (%s)" % (self.name, self.parent) diff --git a/tests/related_resource/tests.py b/tests/related_resource/tests.py index e3ae048ab..d5ac890cb 100644 --- a/tests/related_resource/tests.py +++ b/tests/related_resource/tests.py @@ -391,4 +391,43 @@ def test_put(self): ContentType.objects.get_for_model(Taggable)))) resp = resource.put_detail(request, pk=data['id']) self.assertEqual(resp.status_code, 204) - self.assertEqual(GenericTag.objects.get(pk=data['id']).content_type, ContentType.objects.get_for_model(Taggable)) \ No newline at end of file + self.assertEqual(GenericTag.objects.get(pk=data['id']).content_type, ContentType.objects.get_for_model(Taggable)) + + def test_reverse(self): + tags = self.category_1.tags.all() + + request = MockRequest() + request.GET = {'format': 'json'} + request.method = 'GET' + + resource = api.canonical_resource_for('generictag') + resource.fields['content_object'].full = False + # should get us self.tag_1 + resp = resource.wrap_view('dispatch_detail')(request, pk=self.tag_1.pk) + self.assertEqual(resp.status_code, 200) + data = json.loads(resp.content) + # test that the uri for content_object pointed to self.category_1 + self.assertEqual(data['content_object'], + CategoryResource().get_resource_uri(self.category_1)) + + resp = self.client.get(data['content_object'], data={"format": "json"}) + self.assertEqual(resp.status_code, 200) + data = json.loads(resp.content) + tags_urls = list() + for tag in tags: + tags_urls.append(GenericTagResource().get_resource_uri(tag)) + self.assertEqual(data['tags'], tags_urls) + + # add some more tags to this category + GenericTag.objects.create(name="Object Orientated", content_object=self.category_1) + GenericTag.objects.create(name="Interpreted", content_object=self.category_1) + + tags = self.category_1.tags.all() + tags_urls = list() + for tag in tags: + tags_urls.append(GenericTagResource().get_resource_uri(tag)) + + resp = self.client.get(data['resource_uri'], data={"format": "json"}) + self.assertEqual(resp.status_code, 200) + data = json.loads(resp.content) + self.assertEqual(data['tags'], tags_urls) \ No newline at end of file