Merge pull request #5174 from tadhg-ohiggins/html_cutoff_none

Fix exception when HTML_CUTOFF is set to None
This commit is contained in:
Tom Christie 2017-05-29 11:54:03 +01:00 committed by GitHub
commit e2157fbf7c
3 changed files with 74 additions and 10 deletions

View File

@ -75,7 +75,8 @@ class PKOnlyObject(object):
# rather than the parent serializer.
MANY_RELATION_KWARGS = (
'read_only', 'write_only', 'required', 'default', 'initial', 'source',
'label', 'help_text', 'style', 'error_messages', 'allow_empty'
'label', 'help_text', 'style', 'error_messages', 'allow_empty',
'html_cutoff', 'html_cutoff_text'
)
@ -86,10 +87,12 @@ class RelatedField(Field):
def __init__(self, **kwargs):
self.queryset = kwargs.pop('queryset', self.queryset)
self.html_cutoff = kwargs.pop(
'html_cutoff',
self.html_cutoff or int(api_settings.HTML_SELECT_CUTOFF)
)
cutoff_from_settings = api_settings.HTML_SELECT_CUTOFF
if cutoff_from_settings is not None:
cutoff_from_settings = int(cutoff_from_settings)
self.html_cutoff = kwargs.pop('html_cutoff', cutoff_from_settings)
self.html_cutoff_text = kwargs.pop(
'html_cutoff_text',
self.html_cutoff_text or _(api_settings.HTML_SELECT_CUTOFF_TEXT)
@ -466,10 +469,12 @@ class ManyRelatedField(Field):
def __init__(self, child_relation=None, *args, **kwargs):
self.child_relation = child_relation
self.allow_empty = kwargs.pop('allow_empty', True)
self.html_cutoff = kwargs.pop(
'html_cutoff',
self.html_cutoff or int(api_settings.HTML_SELECT_CUTOFF)
)
cutoff_from_settings = api_settings.HTML_SELECT_CUTOFF
if cutoff_from_settings is not None:
cutoff_from_settings = int(cutoff_from_settings)
self.html_cutoff = kwargs.pop('html_cutoff', cutoff_from_settings)
self.html_cutoff_text = kwargs.pop(
'html_cutoff_text',
self.html_cutoff_text or _(api_settings.HTML_SELECT_CUTOFF_TEXT)

View File

@ -1,12 +1,13 @@
import uuid
import pytest
from _pytest.monkeypatch import MonkeyPatch
from django.conf.urls import url
from django.core.exceptions import ImproperlyConfigured
from django.test import override_settings
from django.utils.datastructures import MultiValueDict
from rest_framework import serializers
from rest_framework import relations, serializers
from rest_framework.fields import empty
from rest_framework.test import APISimpleTestCase
@ -25,6 +26,61 @@ class TestStringRelatedField(APISimpleTestCase):
assert representation == '<MockObject name=foo, pk=1>'
class MockApiSettings(object):
def __init__(self, cutoff, cutoff_text):
self.HTML_SELECT_CUTOFF = cutoff
self.HTML_SELECT_CUTOFF_TEXT = cutoff_text
class TestRelatedFieldHTMLCutoff(APISimpleTestCase):
def setUp(self):
self.queryset = MockQueryset([
MockObject(pk=i, name=str(i)) for i in range(0, 1100)
])
self.monkeypatch = MonkeyPatch()
def test_no_settings(self):
# The default is 1,000, so sans settings it should be 1,000 plus one.
for many in (False, True):
field = serializers.PrimaryKeyRelatedField(queryset=self.queryset,
many=many)
options = list(field.iter_options())
assert len(options) == 1001
assert options[-1].display_text == "More than 1000 items..."
def test_settings_cutoff(self):
self.monkeypatch.setattr(relations, "api_settings",
MockApiSettings(2, "Cut Off"))
for many in (False, True):
field = serializers.PrimaryKeyRelatedField(queryset=self.queryset,
many=many)
options = list(field.iter_options())
assert len(options) == 3 # 2 real items plus the 'Cut Off' item.
assert options[-1].display_text == "Cut Off"
def test_settings_cutoff_none(self):
# Setting it to None should mean no limit; the default limit is 1,000.
self.monkeypatch.setattr(relations, "api_settings",
MockApiSettings(None, "Cut Off"))
for many in (False, True):
field = serializers.PrimaryKeyRelatedField(queryset=self.queryset,
many=many)
options = list(field.iter_options())
assert len(options) == 1100
def test_settings_kwargs_cutoff(self):
# The explicit argument should override the settings.
self.monkeypatch.setattr(relations, "api_settings",
MockApiSettings(2, "Cut Off"))
for many in (False, True):
field = serializers.PrimaryKeyRelatedField(queryset=self.queryset,
many=many,
html_cutoff=100)
options = list(field.iter_options())
assert len(options) == 101
assert options[-1].display_text == "Cut Off"
class TestPrimaryKeyRelatedField(APISimpleTestCase):
def setUp(self):
self.queryset = MockQueryset([

View File

@ -20,6 +20,9 @@ class MockQueryset(object):
def __init__(self, iterable):
self.items = iterable
def __getitem__(self, val):
return self.items[val]
def get(self, **lookup):
for item in self.items:
if all([