diff options
| author | Tom Christie | 2013-10-02 16:13:34 +0100 | 
|---|---|---|
| committer | Tom Christie | 2013-10-02 16:13:34 +0100 | 
| commit | 8d4ba478cc5725b4de6ab86b4825b1ea94cb4c7b (patch) | |
| tree | 75187b1e1d5bd77dd4f137b467da5ce7a5b09603 /rest_framework | |
| parent | a14f1e886402b8d0f742fdbb912b03a4004e1735 (diff) | |
| download | django-rest-framework-8d4ba478cc5725b4de6ab86b4825b1ea94cb4c7b.tar.bz2 | |
Fix rendering of forms and add error rendering on HTML form
Diffstat (limited to 'rest_framework')
| -rw-r--r-- | rest_framework/renderers.py | 16 | ||||
| -rw-r--r-- | rest_framework/serializers.py | 26 | ||||
| -rw-r--r-- | rest_framework/templates/rest_framework/base.html | 4 | ||||
| -rw-r--r-- | rest_framework/templates/rest_framework/raw_data_form.html | 12 | 
4 files changed, 39 insertions, 19 deletions
diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index 0e17edaf..fe4f43d4 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -419,6 +419,13 @@ class BrowsableAPIRenderer(BaseRenderer):          In the absence of the View having an associated form then return None.          """ +        if request.method == method: +            data = request.DATA +            files = request.FILES +        else: +            data = None +            files = None +          with override_method(view, request, method) as request:              obj = getattr(view, 'object', None)              if not self.show_form_for_method(view, method, request, obj): @@ -431,9 +438,10 @@ class BrowsableAPIRenderer(BaseRenderer):                  or not any(is_form_media_type(parser.media_type) for parser in view.parser_classes)):                  return -            serializer = view.get_serializer(instance=obj) - +            serializer = view.get_serializer(instance=obj, data=data, files=files) +            serializer.is_valid()              data = serializer.data +              form_renderer = self.form_renderer_class()              return form_renderer.render(data, self.accepted_media_type, self.renderer_context) @@ -525,6 +533,7 @@ class BrowsableAPIRenderer(BaseRenderer):          renderer = self.get_default_renderer(view) +        raw_data_post_form = self.get_raw_data_form(view, 'POST', request)          raw_data_put_form = self.get_raw_data_form(view, 'PUT', request)          raw_data_patch_form = self.get_raw_data_form(view, 'PATCH', request)          raw_data_put_or_patch_form = raw_data_put_form or raw_data_patch_form @@ -543,12 +552,11 @@ class BrowsableAPIRenderer(BaseRenderer):              'put_form': self.get_rendered_html_form(view, 'PUT', request),              'post_form': self.get_rendered_html_form(view, 'POST', request), -            'patch_form': self.get_rendered_html_form(view, 'PATCH', request),              'delete_form': self.get_rendered_html_form(view, 'DELETE', request),              'options_form': self.get_rendered_html_form(view, 'OPTIONS', request),              'raw_data_put_form': raw_data_put_form, -            'raw_data_post_form': self.get_raw_data_form(view, 'POST', request), +            'raw_data_post_form': raw_data_post_form,              'raw_data_patch_form': raw_data_patch_form,              'raw_data_put_or_patch_form': raw_data_put_or_patch_form, diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 206a8123..bc9f73d1 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -308,24 +308,14 @@ class BaseSerializer(WritableField):          """          ret = self._dict_class()          ret.fields = self._dict_class() -        ret.empty = obj is None          for field_name, field in self.fields.items():              field.initialize(parent=self, field_name=field_name)              key = self.get_field_key(field_name) -            if self._errors: -                value = self.init_data.get(field_name) -            else: -                value = field.field_to_native(obj, field_name) - -            field._errors = self._errors.get(key) if self._errors else None -            field._name = field_name -            field._value = value -            if not field.label: -                field.label = pretty_name(key) - +            value = field.field_to_native(obj, field_name)              ret[key] = value -            ret.fields[key] = field +            ret.fields[key] = self.augment_field(field, field_name, key, value) +          return ret      def from_native(self, data, files): @@ -333,6 +323,7 @@ class BaseSerializer(WritableField):          Deserialize primitives -> objects.          """          self._errors = {} +          if data is not None or files is not None:              attrs = self.restore_fields(data, files)              if attrs is not None: @@ -343,6 +334,15 @@ class BaseSerializer(WritableField):          if not self._errors:              return self.restore_object(attrs, instance=getattr(self, 'object', None)) +    def augment_field(self, field, field_name, key, value): +        # This horrible stuff is to manage serializers rendering to HTML +        field._errors = self._errors.get(key) if self._errors else None +        field._name = field_name +        field._value = self.init_data.get(key) if self._errors and self.init_data else value +        if not field.label: +            field.label = pretty_name(key) +        return field +      def field_to_native(self, obj, field_name):          """          Override default so that the serializer can be used as a nested field diff --git a/rest_framework/templates/rest_framework/base.html b/rest_framework/templates/rest_framework/base.html index 2776d550..33be36db 100644 --- a/rest_framework/templates/rest_framework/base.html +++ b/rest_framework/templates/rest_framework/base.html @@ -151,7 +151,7 @@                              {% with form=raw_data_post_form %}                              <form action="{{ request.get_full_path }}" method="POST" class="form-horizontal">                                  <fieldset> -                                    {% include "rest_framework/form.html" %} +                                    {% include "rest_framework/raw_data_form.html" %}                                      <div class="form-actions">                                          <button class="btn btn-primary" title="Make a POST request on the {{ name }} resource">POST</button>                                      </div> @@ -188,7 +188,7 @@                              {% with form=raw_data_put_or_patch_form %}                              <form action="{{ request.get_full_path }}" method="POST" class="form-horizontal">                                  <fieldset> -                                    {% include "rest_framework/form.html" %} +                                    {% include "rest_framework/raw_data_form.html" %}                                      <div class="form-actions">                                          {% if raw_data_put_form %}                                          <button class="btn btn-primary js-tooltip" name="{{ api_settings.FORM_METHOD_OVERRIDE }}" value="PUT" title="Make a PUT request on the {{ name }} resource">PUT</button> diff --git a/rest_framework/templates/rest_framework/raw_data_form.html b/rest_framework/templates/rest_framework/raw_data_form.html new file mode 100644 index 00000000..075279f7 --- /dev/null +++ b/rest_framework/templates/rest_framework/raw_data_form.html @@ -0,0 +1,12 @@ +{% load rest_framework %} +{% csrf_token %} +{{ form.non_field_errors }} +{% for field in form %} +    <div class="control-group"> +        {{ field.label_tag|add_class:"control-label" }} +        <div class="controls"> +            {{ field }} +            <span class="help-block">{{ field.help_text }}</span> +        </div> +    </div> +{% endfor %}  | 
