diff options
Diffstat (limited to 'rest_framework')
33 files changed, 324 insertions, 15 deletions
| diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index 225f9fe8..6483a47c 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -13,17 +13,18 @@ import django  from django import forms  from django.core.exceptions import ImproperlyConfigured  from django.http.multipartparser import parse_header -from django.template import RequestContext, loader, Template +from django.template import Context, RequestContext, loader, Template  from django.test.client import encode_multipart  from django.utils import six  from django.utils.xmlutils import SimplerXMLGenerator +from rest_framework import exceptions, serializers, status, VERSION  from rest_framework.compat import StringIO, smart_text, yaml  from rest_framework.exceptions import ParseError  from rest_framework.settings import api_settings  from rest_framework.request import is_form_media_type, override_method  from rest_framework.utils import encoders  from rest_framework.utils.breadcrumbs import get_breadcrumbs -from rest_framework import exceptions, status, VERSION +from rest_framework.utils.field_mapping import ClassLookupDict  def zero_as_none(value): @@ -341,6 +342,42 @@ class HTMLFormRenderer(BaseRenderer):      template = 'rest_framework/form.html'      charset = 'utf-8' +    field_templates = ClassLookupDict({ +        serializers.Field: { +            'default': 'input.html' +        }, +        serializers.BooleanField: { +            'default': 'checkbox.html' +        }, +        serializers.CharField: { +            'default': 'input.html', +            'textarea': 'textarea.html' +        }, +        serializers.ChoiceField: { +            'default': 'select.html', +            'radio': 'select_radio.html' +        }, +        serializers.MultipleChoiceField: { +            'default': 'select_multiple.html', +            'checkbox': 'select_checkbox.html' +        } +    }) + +    def render_field(self, field, value, errors, layout=None): +        layout = layout or 'vertical' +        style_type = field.style.get('type', 'default') +        if style_type == 'textarea' and layout == 'inline': +            style_type = 'default' +        base = self.field_templates[field][style_type] +        template_name = 'rest_framework/fields/' + layout + '/' + base +        template = loader.get_template(template_name) +        context = Context({ +            'field': field, +            'value': value, +            'errors': errors +        }) +        return template.render(context) +      def render(self, data, accepted_media_type=None, renderer_context=None):          """          Render serializer data and return an HTML form, as a string. @@ -349,7 +386,11 @@ class HTMLFormRenderer(BaseRenderer):          request = renderer_context['request']          template = loader.get_template(self.template) -        context = RequestContext(request, {'form': data}) +        context = RequestContext(request, { +            'form': data, +            'layout': getattr(getattr(data, 'Meta', None), 'layout', 'vertical'), +            'renderer': self +        })          return template.render(context) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 0faa5671..5da81247 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -302,6 +302,8 @@ class Serializer(BaseSerializer):      def __iter__(self):          errors = self.errors if hasattr(self, '_errors') else {}          for field in self.fields.values(): +            if field.read_only: +                continue              value = self.data.get(field.field_name) if self.data else None              error = errors.get(field.field_name)              yield FieldResult(field, value, error) diff --git a/rest_framework/templates/rest_framework/fields/attrs.html b/rest_framework/templates/rest_framework/fields/attrs.html new file mode 100644 index 00000000..b5a4dbcf --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/attrs.html @@ -0,0 +1 @@ +name="{{ field.field_name }}" {% if field.style.placeholder %}placeholder="{{ field.style.placeholder }}"{% endif %} {% if field.style.rows %}rows="{{ field.style.rows }}"{% endif %} diff --git a/rest_framework/templates/rest_framework/fields/horizontal/checkbox.html b/rest_framework/templates/rest_framework/fields/horizontal/checkbox.html new file mode 100644 index 00000000..dce4a5cf --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/horizontal/checkbox.html @@ -0,0 +1,10 @@ +<div class="form-group"> +    <div class="col-sm-offset-2 col-sm-10"> +        <div class="checkbox"> +            <label> +                <input type="checkbox" name="{{ field.field_name }}" value="true" {% if value %}checked{% endif %}> +                {% if field.label %}{{ field.label }}{% endif %} +            </label> +        </div> +    </div> +</div> diff --git a/rest_framework/templates/rest_framework/fields/horizontal/fieldset.html b/rest_framework/templates/rest_framework/fields/horizontal/fieldset.html new file mode 100644 index 00000000..86417633 --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/horizontal/fieldset.html @@ -0,0 +1,10 @@ +<fieldset> +    {% if field.label %} +        <div class="form-group" style="border-bottom: 1px solid #e5e5e5"> +            <legend class="control-label col-sm-2 {% if field.style.hide_label %}sr-only{% endif %}" style="border-bottom: 0">{{ field.label }}</legend> +        </div> +    {% endif %} +    {% for field_item in value.field_items.values() %} +        {{ renderer.render_field(field_item, layout=layout) }} +    {% endfor %} +</fieldset> diff --git a/rest_framework/templates/rest_framework/fields/horizontal/input.html b/rest_framework/templates/rest_framework/fields/horizontal/input.html new file mode 100644 index 00000000..310154bb --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/horizontal/input.html @@ -0,0 +1,7 @@ +<div class="form-group"> +    {% include "rest_framework/fields/horizontal/label.html" %} +    <div class="col-sm-10"> +        <input type="{{ input_type }}" class="form-control" {% include "rest_framework/fields/attrs.html" %} {% if value %}value="{{ value }}"{% endif %}> +        {% if field.help_text %}<p class="help-block">{{ field.help_text }}</p>{% endif %} +    </div> +</div> diff --git a/rest_framework/templates/rest_framework/fields/horizontal/label.html b/rest_framework/templates/rest_framework/fields/horizontal/label.html new file mode 100644 index 00000000..bf21f78c --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/horizontal/label.html @@ -0,0 +1 @@ +{% if field.label %}<label class="col-sm-2 control-label {% if field.style.hide_label %}sr-only{% endif %}">{{ field.label }}</label>{% endif %} diff --git a/rest_framework/templates/rest_framework/fields/horizontal/select.html b/rest_framework/templates/rest_framework/fields/horizontal/select.html new file mode 100644 index 00000000..3f8cab0a --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/horizontal/select.html @@ -0,0 +1,10 @@ +<div class="form-group"> +    {% include "rest_framework/fields/horizontal/label.html" %} +    <div class="col-sm-10"> +        <select class="form-control" name="{{ field.field_name }}"> +            {% for key, text in field.choices.items %} +            <option value="{{ key }}" {% if key == value %}selected{% endif %}>{{ text }}</option> +            {% endfor %} +        </select> +    </div> +</div> diff --git a/rest_framework/templates/rest_framework/fields/horizontal/select_checkbox.html b/rest_framework/templates/rest_framework/fields/horizontal/select_checkbox.html new file mode 100644 index 00000000..659eede8 --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/horizontal/select_checkbox.html @@ -0,0 +1,22 @@ +<div class="form-group"> +    {% include "rest_framework/fields/horizontal/label.html" %} +    <div class="col-sm-10"> +    {% if field.style.inline %} +        {% for key, text in field.choices.items %} +            <label class="checkbox-inline"> +                <input type="checkbox" name="{{ field.field_name }}" value="{{ key }}" {% if key in value %}checked{% endif %}> +                {{ text }} +            </label> +        {% endfor %} +    {% else %} +        {% for key, text in field.choices.items %} +            <div class="checkbox"> +                <label> +                    <input type="checkbox" name="{{ field.field_name }}" value="{{ key }}" {% if key in value %}checked{% endif %}> +                    {{ text }} +                </label> +            </div> +        {% endfor %} +    {% endif %} +    </div> +</div> diff --git a/rest_framework/templates/rest_framework/fields/horizontal/select_multiple.html b/rest_framework/templates/rest_framework/fields/horizontal/select_multiple.html new file mode 100644 index 00000000..da25eb2b --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/horizontal/select_multiple.html @@ -0,0 +1,10 @@ +<div class="form-group"> +    {% include "rest_framework/fields/horizontal/label.html" %} +    <div class="col-sm-10"> +        <select multiple class="form-control" name="{{ field.field_name }}"> +            {% for key, text in field.choices.items %} +            <option value="{{ key }}" {% if key in value %}selected{% endif %}>{{ text }}</option> +            {% endfor %} +        </select> +    </div> +</div> diff --git a/rest_framework/templates/rest_framework/fields/horizontal/select_radio.html b/rest_framework/templates/rest_framework/fields/horizontal/select_radio.html new file mode 100644 index 00000000..188f05e2 --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/horizontal/select_radio.html @@ -0,0 +1,22 @@ +<div class="form-group"> +    {% include "rest_framework/fields/horizontal/label.html" %} +    <div class="col-sm-10"> +    {% if field.style.inline %} +        {% for key, text in field.choices.items %} +            <label class="radio-inline"> +                <input type="radio" name="{{ field.field_name }}" value="{{ key }}" {% if key == value %}checked{% endif %}> +                {{ text }} +            </label> +        {% endfor %} +    {% else %} +        {% for key, text in field.choices.items %} +            <div class="radio"> +                <label> +                    <input type="radio" name="{{ field.field_name }}" value="{{ key }}" {% if key == value %}checked{% endif %}> +                    {{ text }} +                </label> +            </div> +        {% endfor %} +    {% endif %} +    </div> +</div> diff --git a/rest_framework/templates/rest_framework/fields/horizontal/textarea.html b/rest_framework/templates/rest_framework/fields/horizontal/textarea.html new file mode 100644 index 00000000..e99266f3 --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/horizontal/textarea.html @@ -0,0 +1,7 @@ +<div class="form-group"> +    {% include "rest_framework/fields/horizontal/label.html" %} +    <div class="col-sm-10"> +        <textarea class="form-control" {% include "rest_framework/fields/attrs.html" %}>{% if value %}{{ value }}{% endif %}</textarea> +        {% if field.help_text %}<p class="help-block">{{ field.help_text }}</p>{% endif %} +    </div> +</div> diff --git a/rest_framework/templates/rest_framework/fields/inline/checkbox.html b/rest_framework/templates/rest_framework/fields/inline/checkbox.html new file mode 100644 index 00000000..01d30aae --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/inline/checkbox.html @@ -0,0 +1,6 @@ +<div class="checkbox"> +    <label> +        <input type="checkbox" name="{{ field.field_name }}" value="true" {% if value %}checked{% endif %}> +        {% if field.label %}{{ field.label }}{% endif %} +    </label> +</div> diff --git a/rest_framework/templates/rest_framework/fields/inline/fieldset.html b/rest_framework/templates/rest_framework/fields/inline/fieldset.html new file mode 100644 index 00000000..d22982fd --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/inline/fieldset.html @@ -0,0 +1,3 @@ +{% for field_item in value.field_items.values() %} +    {{ renderer.render_field(field_item, layout=layout) }} +{% endfor %} diff --git a/rest_framework/templates/rest_framework/fields/inline/input.html b/rest_framework/templates/rest_framework/fields/inline/input.html new file mode 100644 index 00000000..aefd1672 --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/inline/input.html @@ -0,0 +1,4 @@ +<div class="form-group"> +    {% include "rest_framework/fields/inline/label.html" %} +    <input type="{{ input_type }}" class="form-control" {% include "rest_framework/fields/attrs.html" %} {% if value %}value="{{ value }}"{% endif %}> +</div> diff --git a/rest_framework/templates/rest_framework/fields/inline/label.html b/rest_framework/templates/rest_framework/fields/inline/label.html new file mode 100644 index 00000000..7d546a57 --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/inline/label.html @@ -0,0 +1 @@ +{% if field.label %}<label class="sr-only">{{ field.label }}</label>{% endif %} diff --git a/rest_framework/templates/rest_framework/fields/inline/select.html b/rest_framework/templates/rest_framework/fields/inline/select.html new file mode 100644 index 00000000..cb9a7013 --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/inline/select.html @@ -0,0 +1,8 @@ +<div class="form-group"> +    {% include "rest_framework/fields/inline/label.html" %} +    <select class="form-control" name="{{ field.field_name }}"> +        {% for key, text in field.choices.items %} +        <option value="{{ key }}" {% if key == value %}selected{% endif %}>{{ text }}</option> +        {% endfor %} +    </select> +</div> diff --git a/rest_framework/templates/rest_framework/fields/inline/select_checkbox.html b/rest_framework/templates/rest_framework/fields/inline/select_checkbox.html new file mode 100644 index 00000000..424df93e --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/inline/select_checkbox.html @@ -0,0 +1,11 @@ +<div class="form-group"> +    {% include "rest_framework/fields/inline/label.html" %} +    {% for key, text in field.choices.items %} +    <div class="checkbox"> +        <label> +            <input type="checkbox" name="{{ rest_framework/field.field_name }}" value="{{ key }}" {% if key in value %}checked{% endif %}> +            {{ text }} +        </label> +    </div> +    {% endfor %} +</div> diff --git a/rest_framework/templates/rest_framework/fields/inline/select_multiple.html b/rest_framework/templates/rest_framework/fields/inline/select_multiple.html new file mode 100644 index 00000000..6fdfd672 --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/inline/select_multiple.html @@ -0,0 +1,8 @@ +<div class="form-group"> +    {% include "rest_framework/fields/inline/label.html" %} +    <select multiple class="form-control" name="{{ field.field_name }}"> +        {% for key, text in field.choices.items %} +        <option value="{{ key }}" {% if key in value %}selected{% endif %}>{{ text }}</option> +        {% endfor %} +    </select> +</div> diff --git a/rest_framework/templates/rest_framework/fields/inline/select_radio.html b/rest_framework/templates/rest_framework/fields/inline/select_radio.html new file mode 100644 index 00000000..ddabc9e9 --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/inline/select_radio.html @@ -0,0 +1,11 @@ +<div class="form-group"> +    {% include "rest_framework/fields/inline/label.html" %} +    {% for key, text in field.choices.items %} +        <div class="radio"> +            <label> +                <input type="radio" name="{{ field.field_name }}" value="{{ key }}" {% if key == value %}checked{% endif %}> +                {{ text }} +            </label> +        </div> +    {% endfor %} +</div> diff --git a/rest_framework/templates/rest_framework/fields/inline/textarea.html b/rest_framework/templates/rest_framework/fields/inline/textarea.html new file mode 100644 index 00000000..31366809 --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/inline/textarea.html @@ -0,0 +1,4 @@ +<div class="form-group"> +    {% include "rest_framework/fields/inline/label.html" %} +    <textarea class="form-control" {% include "rest_framework/fields/attrs.html" %}>{% if value %}{{ value }}{% endif %}</textarea> +</div> diff --git a/rest_framework/templates/rest_framework/fields/vertical/checkbox.html b/rest_framework/templates/rest_framework/fields/vertical/checkbox.html new file mode 100644 index 00000000..01d30aae --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/vertical/checkbox.html @@ -0,0 +1,6 @@ +<div class="checkbox"> +    <label> +        <input type="checkbox" name="{{ field.field_name }}" value="true" {% if value %}checked{% endif %}> +        {% if field.label %}{{ field.label }}{% endif %} +    </label> +</div> diff --git a/rest_framework/templates/rest_framework/fields/vertical/fieldset.html b/rest_framework/templates/rest_framework/fields/vertical/fieldset.html new file mode 100644 index 00000000..cad32df9 --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/vertical/fieldset.html @@ -0,0 +1,6 @@ +<fieldset> +    {% if field.label %}<legend {% if field.style.hide_label %}class="sr-only"{% endif %}>{{ field.label }}</legend>{% endif %} +    {% for field_item in value.field_items.values() %} +        {{ renderer.render_field(field_item, layout=layout) }} +    {% endfor %} +</fieldset> diff --git a/rest_framework/templates/rest_framework/fields/vertical/input.html b/rest_framework/templates/rest_framework/fields/vertical/input.html new file mode 100644 index 00000000..c25407d1 --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/vertical/input.html @@ -0,0 +1,5 @@ +<div class="form-group"> +    {% include "rest_framework/fields/vertical/label.html" %} +    <input type="{{ input_type }}" class="form-control" {% include "rest_framework/fields/attrs.html" %} {% if value %}value="{{ value }}"{% endif %}> +    {% if field.help_text %}<p class="help-block">{{ field.help_text }}</p>{% endif %} +</div> diff --git a/rest_framework/templates/rest_framework/fields/vertical/label.html b/rest_framework/templates/rest_framework/fields/vertical/label.html new file mode 100644 index 00000000..651939b2 --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/vertical/label.html @@ -0,0 +1 @@ +{% if field.label %}<label {% if field.style.hide_label %}class="sr-only"{% endif %}>{{ field.label }}</label>{% endif %} diff --git a/rest_framework/templates/rest_framework/fields/vertical/select.html b/rest_framework/templates/rest_framework/fields/vertical/select.html new file mode 100644 index 00000000..44679d8a --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/vertical/select.html @@ -0,0 +1,8 @@ +<div class="form-group"> +    {% include "rest_framework/fields/vertical/label.html" %} +    <select class="form-control" name="{{ field.field_name }}"> +        {% for key, text in field.choices.items %} +        <option value="{{ key }}" {% if key == value %}selected{% endif %}>{{ text }}</option> +        {% endfor %} +    </select> +</div> diff --git a/rest_framework/templates/rest_framework/fields/vertical/select_checkbox.html b/rest_framework/templates/rest_framework/fields/vertical/select_checkbox.html new file mode 100644 index 00000000..e60574c0 --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/vertical/select_checkbox.html @@ -0,0 +1,22 @@ +<div class="form-group"> +    {% include "rest_framework/fields/vertical/label.html" %} +    {% if field.style.inline %} +        <div> +        {% for key, text in field.choices.items %} +            <label class="checkbox-inline"> +                <input type="checkbox" name="{{ field.field_name }}" value="{{ key }}" {% if key in value %}checked{% endif %}> +                {{ text }} +            </label> +        {% endfor %} +        </div> +    {% else %} +        {% for key, text in field.choices.items %} +        <div class="checkbox"> +            <label> +                <input type="checkbox" name="{{ field.field_name }}" value="{{ key }}" {% if key in value %}checked{% endif %}> +                {{ text }} +            </label> +        </div> +        {% endfor %} +    {% endif %} +</div> diff --git a/rest_framework/templates/rest_framework/fields/vertical/select_multiple.html b/rest_framework/templates/rest_framework/fields/vertical/select_multiple.html new file mode 100644 index 00000000..f0fa418b --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/vertical/select_multiple.html @@ -0,0 +1,8 @@ +<div class="form-group"> +    {% include "rest_framework/fields/vertical/label.html" %} +    <select multiple class="form-control" name="{{ field.field_name }}"> +        {% for key, text in field.choices.items() %} +        <option value="{{ key }}" {% if key in value %}selected{% endif %}>{{ text }}</option> +        {% endfor %} +    </select> +</div> diff --git a/rest_framework/templates/rest_framework/fields/vertical/select_radio.html b/rest_framework/templates/rest_framework/fields/vertical/select_radio.html new file mode 100644 index 00000000..4ffe38ea --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/vertical/select_radio.html @@ -0,0 +1,22 @@ +<div class="form-group"> +    {% include "rest_framework/fields/vertical/label.html" %} +    {% if field.style.inline %} +        <div> +        {% for key, text in field.choices.items %} +            <label class="radio-inline"> +                <input type="radio" name="{{ field.field_name }}" value="{{ key }}" {% if key|string==value|string %}checked{% endif %}> +                {{ text }} +            </label> +        {% endfor %} +        </div> +    {% else %} +        {% for key, text in field.choices.items %} +            <div class="radio"> +                <label> +                    <input type="radio" name="{{ field.field_name }}" value="{{ key }}" {% if key|string==value|string %}checked{% endif %}> +                    {{ text }} +                </label> +            </div> +        {% endfor %} +    {% endif %} +</div> diff --git a/rest_framework/templates/rest_framework/fields/vertical/textarea.html b/rest_framework/templates/rest_framework/fields/vertical/textarea.html new file mode 100644 index 00000000..33cb27c7 --- /dev/null +++ b/rest_framework/templates/rest_framework/fields/vertical/textarea.html @@ -0,0 +1,5 @@ +<div class="form-group"> +    {% include "rest_framework/fields/vertical/label.html" %} +    <textarea class="form-control" {% include "rest_framework/fields/attrs.html" %}>{% if value %}{{ value }}{% endif %}</textarea> +    {% if field.help_text %}<p class="help-block">{{ field.help_text }}</p>{% endif %} +</div> diff --git a/rest_framework/templates/rest_framework/form.html b/rest_framework/templates/rest_framework/form.html index b1e148df..64b1b0bc 100644 --- a/rest_framework/templates/rest_framework/form.html +++ b/rest_framework/templates/rest_framework/form.html @@ -1,15 +1,31 @@ +<html> +<head> +    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet"> +</head> +<body> +<div class="container"> + +<h1>User update</h1> +<div class="well"> +  {% load rest_framework %} -{% csrf_token %} -{{ form.non_field_errors }} -{% for field in form.fields.values %} -    {% if not field.read_only %} -    <div class="control-group {% if field.errors %}error{% endif %}"> -        {{ field.label_tag|add_class:"control-label" }} -        <div class="controls"> -            {{ field.widget_html }} -            {% if field.help_text %}<span class="help-block">{{ field.help_text }}</span>{% endif %} -            {% for error in field.errors %}<span class="help-block">{{ error }}</span>{% endfor %} +<form {% if layout == "inline" %}class="form-inline"{% elif layout == "horizontal" %}class="form-horizontal"{% endif %} role="form" action="" method="POST"> +    {% csrf_token %} +    {% for field, value, errors in form %} +        {% render_field field value errors layout=layout renderer=renderer %} +    {% endfor %} +    <!-- form.non_field_errors --> +    {% if layout == "horizontal" %} +        <div class="form-group"> +            <div class="col-sm-offset-2 col-sm-10"> +                <button type="submit" class="btn btn-default">Submit</button> +            </div>          </div> -    </div> +    {% else %} +        <button type="submit" class="btn btn-default">Submit</button>      {% endif %} -{% endfor %} +</form> + +</div> +</div></body> +</html> diff --git a/rest_framework/templatetags/rest_framework.py b/rest_framework/templatetags/rest_framework.py index 864d64dd..88ff9d4e 100644 --- a/rest_framework/templatetags/rest_framework.py +++ b/rest_framework/templatetags/rest_framework.py @@ -31,6 +31,14 @@ class_re = re.compile(r'(?<=class=["\'])(.*)(?=["\'])')  # And the template tags themselves... +# @register.simple_tag +# def render_field(field, value, errors, renderer): +#     return renderer.render_field(field, value, errors) +@register.simple_tag +def render_field(field, value, errors, layout=None, renderer=None): +    return renderer.render_field(field, value, errors, layout) + +  @register.simple_tag  def optional_login(request):      """ diff --git a/rest_framework/utils/field_mapping.py b/rest_framework/utils/field_mapping.py index cf9d910a..b4d33e39 100644 --- a/rest_framework/utils/field_mapping.py +++ b/rest_framework/utils/field_mapping.py @@ -79,6 +79,9 @@ def get_field_kwargs(field_name, model_field):          kwargs['choices'] = model_field.flatchoices          return kwargs +    if isinstance(model_field, models.TextField): +        kwargs['style'] = {'type': 'textarea'} +      if model_field.null and not isinstance(model_field, models.NullBooleanField):          kwargs['allow_null'] = True | 
