2013-01-04 17:05:31 +04:00
|
|
|
"""
|
|
|
|
General tests for relational fields.
|
|
|
|
"""
|
2013-02-05 00:55:35 +04:00
|
|
|
from __future__ import unicode_literals
|
2014-04-09 21:54:13 +04:00
|
|
|
from django import get_version
|
2013-01-04 03:17:31 +04:00
|
|
|
from django.db import models
|
|
|
|
from django.test import TestCase
|
2014-04-09 21:54:13 +04:00
|
|
|
from django.utils import unittest
|
2013-01-04 03:17:31 +04:00
|
|
|
from rest_framework import serializers
|
2014-03-02 15:40:30 +04:00
|
|
|
from tests.models import BlogPost
|
2013-01-04 03:17:31 +04:00
|
|
|
|
|
|
|
|
|
|
|
class NullModel(models.Model):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class FieldTests(TestCase):
|
|
|
|
def test_pk_related_field_with_empty_string(self):
|
|
|
|
"""
|
|
|
|
Regression test for #446
|
|
|
|
|
|
|
|
https://github.com/tomchristie/django-rest-framework/issues/446
|
|
|
|
"""
|
|
|
|
field = serializers.PrimaryKeyRelatedField(queryset=NullModel.objects.all())
|
2013-01-04 17:50:40 +04:00
|
|
|
self.assertRaises(serializers.ValidationError, field.from_native, '')
|
|
|
|
self.assertRaises(serializers.ValidationError, field.from_native, [])
|
|
|
|
|
|
|
|
def test_hyperlinked_related_field_with_empty_string(self):
|
|
|
|
field = serializers.HyperlinkedRelatedField(queryset=NullModel.objects.all(), view_name='')
|
|
|
|
self.assertRaises(serializers.ValidationError, field.from_native, '')
|
|
|
|
self.assertRaises(serializers.ValidationError, field.from_native, [])
|
|
|
|
|
|
|
|
def test_slug_related_field_with_empty_string(self):
|
|
|
|
field = serializers.SlugRelatedField(queryset=NullModel.objects.all(), slug_field='pk')
|
|
|
|
self.assertRaises(serializers.ValidationError, field.from_native, '')
|
|
|
|
self.assertRaises(serializers.ValidationError, field.from_native, [])
|
2013-01-30 16:09:17 +04:00
|
|
|
|
|
|
|
|
2013-05-18 14:16:30 +04:00
|
|
|
class TestManyRelatedMixin(TestCase):
|
2013-01-30 16:09:17 +04:00
|
|
|
def test_missing_many_to_many_related_field(self):
|
|
|
|
'''
|
|
|
|
Regression test for #632
|
|
|
|
|
|
|
|
https://github.com/tomchristie/django-rest-framework/pull/632
|
|
|
|
'''
|
2013-02-07 13:14:58 +04:00
|
|
|
field = serializers.RelatedField(many=True, read_only=False)
|
2013-01-30 16:09:17 +04:00
|
|
|
|
|
|
|
into = {}
|
|
|
|
field.field_from_native({}, None, 'field_name', into)
|
|
|
|
self.assertEqual(into['field_name'], [])
|
2013-05-18 14:16:30 +04:00
|
|
|
|
|
|
|
|
|
|
|
# Regression tests for #694 (`source` attribute on related fields)
|
|
|
|
|
|
|
|
class RelatedFieldSourceTests(TestCase):
|
|
|
|
def test_related_manager_source(self):
|
|
|
|
"""
|
|
|
|
Relational fields should be able to use manager-returning methods as their source.
|
|
|
|
"""
|
|
|
|
BlogPost.objects.create(title='blah')
|
|
|
|
field = serializers.RelatedField(many=True, source='get_blogposts_manager')
|
|
|
|
|
|
|
|
class ClassWithManagerMethod(object):
|
|
|
|
def get_blogposts_manager(self):
|
|
|
|
return BlogPost.objects
|
|
|
|
|
|
|
|
obj = ClassWithManagerMethod()
|
|
|
|
value = field.field_to_native(obj, 'field_name')
|
|
|
|
self.assertEqual(value, ['BlogPost object'])
|
|
|
|
|
|
|
|
def test_related_queryset_source(self):
|
|
|
|
"""
|
|
|
|
Relational fields should be able to use queryset-returning methods as their source.
|
|
|
|
"""
|
|
|
|
BlogPost.objects.create(title='blah')
|
|
|
|
field = serializers.RelatedField(many=True, source='get_blogposts_queryset')
|
|
|
|
|
|
|
|
class ClassWithQuerysetMethod(object):
|
|
|
|
def get_blogposts_queryset(self):
|
|
|
|
return BlogPost.objects.all()
|
|
|
|
|
|
|
|
obj = ClassWithQuerysetMethod()
|
|
|
|
value = field.field_to_native(obj, 'field_name')
|
|
|
|
self.assertEqual(value, ['BlogPost object'])
|
2013-05-18 14:32:48 +04:00
|
|
|
|
|
|
|
def test_dotted_source(self):
|
|
|
|
"""
|
|
|
|
Source argument should support dotted.source notation.
|
|
|
|
"""
|
|
|
|
BlogPost.objects.create(title='blah')
|
|
|
|
field = serializers.RelatedField(many=True, source='a.b.c')
|
|
|
|
|
|
|
|
class ClassWithQuerysetMethod(object):
|
|
|
|
a = {
|
|
|
|
'b': {
|
|
|
|
'c': BlogPost.objects.all()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
obj = ClassWithQuerysetMethod()
|
|
|
|
value = field.field_to_native(obj, 'field_name')
|
|
|
|
self.assertEqual(value, ['BlogPost object'])
|
2014-01-10 02:19:25 +04:00
|
|
|
|
|
|
|
# Regression for #1129
|
|
|
|
def test_exception_for_incorect_fk(self):
|
|
|
|
"""
|
|
|
|
Check that the exception message are correct if the source field
|
|
|
|
doesn't exist.
|
|
|
|
"""
|
2014-03-02 15:40:30 +04:00
|
|
|
from tests.models import ManyToManySource
|
2014-01-10 02:19:25 +04:00
|
|
|
class Meta:
|
|
|
|
model = ManyToManySource
|
|
|
|
attrs = {
|
|
|
|
'name': serializers.SlugRelatedField(
|
|
|
|
slug_field='name', source='banzai'),
|
|
|
|
'Meta': Meta,
|
|
|
|
}
|
|
|
|
|
|
|
|
TestSerializer = type(str('TestSerializer'),
|
|
|
|
(serializers.ModelSerializer,), attrs)
|
|
|
|
with self.assertRaises(AttributeError):
|
|
|
|
TestSerializer(data={'name': 'foo'})
|
2014-04-09 17:51:00 +04:00
|
|
|
|
2014-04-09 21:54:13 +04:00
|
|
|
@unittest.skipIf(get_version() < '1.6.0', 'Upstream behaviour changed in v1.6')
|
2014-04-09 17:51:00 +04:00
|
|
|
class RelatedFieldChoicesTests(TestCase):
|
|
|
|
"""
|
|
|
|
Tests for #1408 "Web browseable API doesn't have blank option on drop down list box"
|
|
|
|
https://github.com/tomchristie/django-rest-framework/issues/1408
|
|
|
|
"""
|
|
|
|
def test_blank_option_is_added_to_choice_if_required_equals_false(self):
|
|
|
|
"""
|
|
|
|
|
|
|
|
"""
|
|
|
|
post = BlogPost(title="Checking blank option is added")
|
|
|
|
post.save()
|
|
|
|
|
|
|
|
queryset = BlogPost.objects.all()
|
|
|
|
field = serializers.RelatedField(required=False, queryset=queryset)
|
|
|
|
|
|
|
|
choice_count = BlogPost.objects.count()
|
|
|
|
widget_count = len(field.widget.choices)
|
|
|
|
|
|
|
|
self.assertEqual(widget_count, choice_count + 1, 'BLANK_CHOICE_DASH option should have been added')
|
|
|
|
|