From 46b9e4edf9ba7c5b10deef4515d287898cdebe38 Mon Sep 17 00:00:00 2001 From: Andy Schriner Date: Mon, 22 Aug 2016 11:38:33 -0700 Subject: [PATCH] add settings for html cutoff on related fields --- docs/api-guide/relations.md | 2 ++ docs/api-guide/settings.md | 16 ++++++++++++++++ rest_framework/relations.py | 31 +++++++++++++++++++++---------- rest_framework/settings.py | 4 ++++ 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/docs/api-guide/relations.md b/docs/api-guide/relations.md index 8695b2c1e..75643a83e 100644 --- a/docs/api-guide/relations.md +++ b/docs/api-guide/relations.md @@ -457,6 +457,8 @@ There are two keyword arguments you can use to control this behavior: - `html_cutoff` - If set this will be the maximum number of choices that will be displayed by a HTML select drop down. Set to `None` to disable any limiting. Defaults to `1000`. - `html_cutoff_text` - If set this will display a textual indicator if the maximum number of items have been cutoff in an HTML select drop down. Defaults to `"More than {count} items…"` +You can also control these globally using the settings `HTML_SELECT_CUTOFF` and `HTML_SELECT_CUTOFF_TEXT`. + In cases where the cutoff is being enforced you may want to instead use a plain input field in the HTML form. You can do so using the `style` keyword argument. For example: assigned_to = serializers.SlugRelatedField( diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md index ea018053f..67d317839 100644 --- a/docs/api-guide/settings.md +++ b/docs/api-guide/settings.md @@ -382,6 +382,22 @@ This should be a function with the following signature: Default: `'rest_framework.views.get_view_description'` +## HTML Select Field cutoffs + +Global settings for [select field cutoffs for rendering relational fields](relations.md#select-field-cutoffs) in the browsable API. + +#### HTML_SELECT_CUTOFF + +Global setting for the `html_cutoff` value. Must be an integer. + +Default: 1000 + +#### HTML_SELECT_CUTOFF_TEXT + +A string representing a global setting for `html_cutoff_text`. + +Default: `"More than {count} items..."` + --- ## Miscellaneous settings diff --git a/rest_framework/relations.py b/rest_framework/relations.py index 65c4c0318..7fe22ec5b 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -18,6 +18,7 @@ from rest_framework.fields import ( Field, empty, get_attribute, is_simple_callable, iter_options ) from rest_framework.reverse import reverse +from rest_framework.settings import api_settings from rest_framework.utils import html @@ -71,14 +72,19 @@ MANY_RELATION_KWARGS = ( class RelatedField(Field): queryset = None - html_cutoff = 1000 - html_cutoff_text = _('More than {count} items...') + html_cutoff = None + html_cutoff_text = None def __init__(self, **kwargs): self.queryset = kwargs.pop('queryset', self.queryset) - self.html_cutoff = kwargs.pop('html_cutoff', self.html_cutoff) - self.html_cutoff_text = kwargs.pop('html_cutoff_text', self.html_cutoff_text) - + self.html_cutoff = kwargs.pop( + 'html_cutoff', + self.html_cutoff or int(api_settings.HTML_SELECT_CUTOFF) + ) + self.html_cutoff_text = kwargs.pop( + 'html_cutoff_text', + self.html_cutoff_text or _(api_settings.HTML_SELECT_CUTOFF_TEXT) + ) if not method_overridden('get_queryset', RelatedField, self): assert self.queryset is not None or kwargs.get('read_only', None), ( 'Relational field must provide a `queryset` argument, ' @@ -447,15 +453,20 @@ class ManyRelatedField(Field): 'not_a_list': _('Expected a list of items but got type "{input_type}".'), 'empty': _('This list may not be empty.') } - html_cutoff = 1000 - html_cutoff_text = _('More than {count} items...') + html_cutoff = None + html_cutoff_text = None 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) - self.html_cutoff_text = kwargs.pop('html_cutoff_text', self.html_cutoff_text) - + self.html_cutoff = kwargs.pop( + 'html_cutoff', + self.html_cutoff or int(api_settings.HTML_SELECT_CUTOFF) + ) + self.html_cutoff_text = kwargs.pop( + 'html_cutoff_text', + self.html_cutoff_text or _(api_settings.HTML_SELECT_CUTOFF_TEXT) + ) assert child_relation is not None, '`child_relation` is a required argument.' super(ManyRelatedField, self).__init__(*args, **kwargs) self.child_relation.bind(field_name='', parent=self) diff --git a/rest_framework/settings.py b/rest_framework/settings.py index 68c7709e8..89e27e743 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -111,6 +111,10 @@ DEFAULTS = { 'COMPACT_JSON': True, 'COERCE_DECIMAL_TO_STRING': True, 'UPLOADED_FILES_USE_URL': True, + + # Browseable API + 'HTML_SELECT_CUTOFF': 1000, + 'HTML_SELECT_CUTOFF_TEXT': "More than {count} items...", }