mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 09:57:55 +03:00 
			
		
		
		
	Merge pull request #857 from pyriku/675-empty-label-related-field
Display an empty label into related fields if it isn't required
This commit is contained in:
		
						commit
						a2e2b0abda
					
				| 
						 | 
				
			
			@ -8,6 +8,7 @@ from __future__ import unicode_literals
 | 
			
		|||
from django.core.exceptions import ObjectDoesNotExist, ValidationError
 | 
			
		||||
from django.core.urlresolvers import resolve, get_script_prefix, NoReverseMatch
 | 
			
		||||
from django import forms
 | 
			
		||||
from django.db.models.fields import BLANK_CHOICE_DASH
 | 
			
		||||
from django.forms import widgets
 | 
			
		||||
from django.forms.models import ModelChoiceIterator
 | 
			
		||||
from django.utils.translation import ugettext_lazy as _
 | 
			
		||||
| 
						 | 
				
			
			@ -47,7 +48,7 @@ class RelatedField(WritableField):
 | 
			
		|||
                          DeprecationWarning, stacklevel=2)
 | 
			
		||||
            kwargs['required'] = not kwargs.pop('null')
 | 
			
		||||
 | 
			
		||||
        self.queryset = kwargs.pop('queryset', None)
 | 
			
		||||
        queryset = kwargs.pop('queryset', None)
 | 
			
		||||
        self.many = kwargs.pop('many', self.many)
 | 
			
		||||
        if self.many:
 | 
			
		||||
            self.widget = self.many_widget
 | 
			
		||||
| 
						 | 
				
			
			@ -56,6 +57,11 @@ class RelatedField(WritableField):
 | 
			
		|||
        kwargs['read_only'] = kwargs.pop('read_only', self.read_only)
 | 
			
		||||
        super(RelatedField, self).__init__(*args, **kwargs)
 | 
			
		||||
 | 
			
		||||
        if not self.required:
 | 
			
		||||
            self.empty_label = BLANK_CHOICE_DASH[0][1]
 | 
			
		||||
 | 
			
		||||
        self.queryset = queryset
 | 
			
		||||
 | 
			
		||||
    def initialize(self, parent, field_name):
 | 
			
		||||
        super(RelatedField, self).initialize(parent, field_name)
 | 
			
		||||
        if self.queryset is None and not self.read_only:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1139,6 +1139,63 @@ class SerializerChoiceFields(TestCase):
 | 
			
		|||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Regression tests for #675
 | 
			
		||||
class Ticket(models.Model):
 | 
			
		||||
    assigned = models.ForeignKey(
 | 
			
		||||
        Person, related_name='assigned_tickets')
 | 
			
		||||
    reviewer = models.ForeignKey(
 | 
			
		||||
        Person, blank=True, null=True, related_name='reviewed_tickets')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SerializerRelatedChoicesTest(TestCase):
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(SerializerRelatedChoicesTest, self).setUp()
 | 
			
		||||
 | 
			
		||||
        class RelatedChoicesSerializer(serializers.ModelSerializer):
 | 
			
		||||
            class Meta:
 | 
			
		||||
                model = Ticket
 | 
			
		||||
                fields = ('assigned', 'reviewer')
 | 
			
		||||
 | 
			
		||||
        self.related_fields_serializer = RelatedChoicesSerializer
 | 
			
		||||
 | 
			
		||||
    def test_empty_queryset_required(self):
 | 
			
		||||
        serializer = self.related_fields_serializer()
 | 
			
		||||
        self.assertEqual(serializer.fields['assigned'].queryset.count(), 0)
 | 
			
		||||
        self.assertEqual(
 | 
			
		||||
            [x for x in serializer.fields['assigned'].widget.choices],
 | 
			
		||||
            []
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_empty_queryset_not_required(self):
 | 
			
		||||
        serializer = self.related_fields_serializer()
 | 
			
		||||
        self.assertEqual(serializer.fields['reviewer'].queryset.count(), 0)
 | 
			
		||||
        self.assertEqual(
 | 
			
		||||
            [x for x in serializer.fields['reviewer'].widget.choices],
 | 
			
		||||
            [('', '---------')]
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_with_some_persons_required(self):
 | 
			
		||||
        Person.objects.create(name="Lionel Messi")
 | 
			
		||||
        Person.objects.create(name="Xavi Hernandez")
 | 
			
		||||
        serializer = self.related_fields_serializer()
 | 
			
		||||
        self.assertEqual(serializer.fields['assigned'].queryset.count(), 2)
 | 
			
		||||
        self.assertEqual(
 | 
			
		||||
            [x for x in serializer.fields['assigned'].widget.choices],
 | 
			
		||||
            [(1, 'Person object - 1'), (2, 'Person object - 2')]
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_with_some_persons_not_required(self):
 | 
			
		||||
        Person.objects.create(name="Lionel Messi")
 | 
			
		||||
        Person.objects.create(name="Xavi Hernandez")
 | 
			
		||||
        serializer = self.related_fields_serializer()
 | 
			
		||||
        self.assertEqual(serializer.fields['reviewer'].queryset.count(), 2)
 | 
			
		||||
        self.assertEqual(
 | 
			
		||||
            [x for x in serializer.fields['reviewer'].widget.choices],
 | 
			
		||||
            [('', '---------'), (1, 'Person object - 1'), (2, 'Person object - 2')]
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DepthTest(TestCase):
 | 
			
		||||
    def test_implicit_nesting(self):
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user