Tests for generic relationships

This commit is contained in:
Tom Christie 2014-10-08 11:22:10 +01:00
parent 093febb912
commit 6b09e5f2bb
3 changed files with 91 additions and 138 deletions

View File

@ -49,7 +49,7 @@ class RelatedField(Field):
]) ])
class StringRelatedField(Field): class StringRelatedField(RelatedField):
""" """
A read only field that represents its targets using their A read only field that represents its targets using their
plain string representation. plain string representation.

View File

@ -520,11 +520,6 @@ class ModelSerializer(Serializer):
ret[field_name] = declared_fields[field_name] ret[field_name] = declared_fields[field_name]
continue continue
elif field_name == api_settings.URL_FIELD_NAME:
# Create the URL field.
field_cls = HyperlinkedIdentityField
kwargs = get_url_kwargs(model)
elif field_name in info.fields_and_pk: elif field_name in info.fields_and_pk:
# Create regular model fields. # Create regular model fields.
model_field = info.fields_and_pk[field_name] model_field = info.fields_and_pk[field_name]
@ -561,6 +556,11 @@ class ModelSerializer(Serializer):
field_cls = ReadOnlyField field_cls = ReadOnlyField
kwargs = {} kwargs = {}
elif field_name == api_settings.URL_FIELD_NAME:
# Create the URL field.
field_cls = HyperlinkedIdentityField
kwargs = get_url_kwargs(model)
else: else:
raise ImproperlyConfigured( raise ImproperlyConfigured(
'Field name `%s` is not valid for model `%s`.' % 'Field name `%s` is not valid for model `%s`.' %

View File

@ -1,151 +1,104 @@
# from __future__ import unicode_literals from __future__ import unicode_literals
# from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
# from django.contrib.contenttypes.generic import GenericRelation, GenericForeignKey from django.contrib.contenttypes.generic import GenericRelation, GenericForeignKey
# from django.db import models from django.db import models
# from django.test import TestCase from django.test import TestCase
# from rest_framework import serializers from rest_framework import serializers
# from rest_framework.compat import python_2_unicode_compatible from rest_framework.compat import python_2_unicode_compatible
# @python_2_unicode_compatible @python_2_unicode_compatible
# class Tag(models.Model): class Tag(models.Model):
# """ """
# Tags have a descriptive slug, and are attached to an arbitrary object. Tags have a descriptive slug, and are attached to an arbitrary object.
# """ """
# tag = models.SlugField() tag = models.SlugField()
# content_type = models.ForeignKey(ContentType) content_type = models.ForeignKey(ContentType)
# object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
# tagged_item = GenericForeignKey('content_type', 'object_id') tagged_item = GenericForeignKey('content_type', 'object_id')
# def __str__(self): def __str__(self):
# return self.tag return self.tag
# @python_2_unicode_compatible @python_2_unicode_compatible
# class Bookmark(models.Model): class Bookmark(models.Model):
# """ """
# A URL bookmark that may have multiple tags attached. A URL bookmark that may have multiple tags attached.
# """ """
# url = models.URLField() url = models.URLField()
# tags = GenericRelation(Tag) tags = GenericRelation(Tag)
# def __str__(self): def __str__(self):
# return 'Bookmark: %s' % self.url return 'Bookmark: %s' % self.url
# @python_2_unicode_compatible @python_2_unicode_compatible
# class Note(models.Model): class Note(models.Model):
# """ """
# A textual note that may have multiple tags attached. A textual note that may have multiple tags attached.
# """ """
# text = models.TextField() text = models.TextField()
# tags = GenericRelation(Tag) tags = GenericRelation(Tag)
# def __str__(self): def __str__(self):
# return 'Note: %s' % self.text return 'Note: %s' % self.text
# class TestGenericRelations(TestCase): class TestGenericRelations(TestCase):
# def setUp(self): def setUp(self):
# self.bookmark = Bookmark.objects.create(url='https://www.djangoproject.com/') self.bookmark = Bookmark.objects.create(url='https://www.djangoproject.com/')
# Tag.objects.create(tagged_item=self.bookmark, tag='django') Tag.objects.create(tagged_item=self.bookmark, tag='django')
# Tag.objects.create(tagged_item=self.bookmark, tag='python') Tag.objects.create(tagged_item=self.bookmark, tag='python')
# self.note = Note.objects.create(text='Remember the milk') self.note = Note.objects.create(text='Remember the milk')
# Tag.objects.create(tagged_item=self.note, tag='reminder') Tag.objects.create(tagged_item=self.note, tag='reminder')
# def test_generic_relation(self): def test_generic_relation(self):
# """ """
# Test a relationship that spans a GenericRelation field. Test a relationship that spans a GenericRelation field.
# IE. A reverse generic relationship. IE. A reverse generic relationship.
# """ """
# class BookmarkSerializer(serializers.ModelSerializer): class BookmarkSerializer(serializers.ModelSerializer):
# tags = serializers.RelatedField(many=True) tags = serializers.StringRelatedField(many=True)
# class Meta: class Meta:
# model = Bookmark model = Bookmark
# exclude = ('id',) fields = ('tags', 'url')
# serializer = BookmarkSerializer(self.bookmark) serializer = BookmarkSerializer(self.bookmark)
# expected = { expected = {
# 'tags': ['django', 'python'], 'tags': ['django', 'python'],
# 'url': 'https://www.djangoproject.com/' 'url': 'https://www.djangoproject.com/'
# } }
# self.assertEqual(serializer.data, expected) self.assertEqual(serializer.data, expected)
# def test_generic_nested_relation(self): def test_generic_fk(self):
# """ """
# Test saving a GenericRelation field via a nested serializer. Test a relationship that spans a GenericForeignKey field.
# """ IE. A forward generic relationship.
"""
# class TagSerializer(serializers.ModelSerializer): class TagSerializer(serializers.ModelSerializer):
# class Meta: tagged_item = serializers.StringRelatedField()
# model = Tag
# exclude = ('content_type', 'object_id')
# class BookmarkSerializer(serializers.ModelSerializer): class Meta:
# tags = TagSerializer(many=True) model = Tag
fields = ('tag', 'tagged_item')
# class Meta: serializer = TagSerializer(Tag.objects.all(), many=True)
# model = Bookmark expected = [
# exclude = ('id',) {
'tag': 'django',
# data = { 'tagged_item': 'Bookmark: https://www.djangoproject.com/'
# 'url': 'https://docs.djangoproject.com/', },
# 'tags': [ {
# {'tag': 'contenttypes'}, 'tag': 'python',
# {'tag': 'genericrelations'}, 'tagged_item': 'Bookmark: https://www.djangoproject.com/'
# ] },
# } {
# serializer = BookmarkSerializer(data=data) 'tag': 'reminder',
# self.assertTrue(serializer.is_valid()) 'tagged_item': 'Note: Remember the milk'
# serializer.save() }
# self.assertEqual(serializer.object.tags.count(), 2) ]
self.assertEqual(serializer.data, expected)
# def test_generic_fk(self):
# """
# Test a relationship that spans a GenericForeignKey field.
# IE. A forward generic relationship.
# """
# class TagSerializer(serializers.ModelSerializer):
# tagged_item = serializers.RelatedField()
# class Meta:
# model = Tag
# exclude = ('id', 'content_type', 'object_id')
# serializer = TagSerializer(Tag.objects.all(), many=True)
# expected = [
# {
# 'tag': 'django',
# 'tagged_item': 'Bookmark: https://www.djangoproject.com/'
# },
# {
# 'tag': 'python',
# 'tagged_item': 'Bookmark: https://www.djangoproject.com/'
# },
# {
# 'tag': 'reminder',
# 'tagged_item': 'Note: Remember the milk'
# }
# ]
# self.assertEqual(serializer.data, expected)
# def test_restore_object_generic_fk(self):
# """
# Ensure an object with a generic foreign key can be restored.
# """
# class TagSerializer(serializers.ModelSerializer):
# class Meta:
# model = Tag
# exclude = ('content_type', 'object_id')
# serializer = TagSerializer()
# bookmark = Bookmark(url='http://example.com')
# attrs = {'tagged_item': bookmark, 'tag': 'example'}
# tag = serializer.restore_object(attrs)
# self.assertEqual(tag.tagged_item, bookmark)