diff options
| author | Tom Christie | 2014-10-02 16:24:24 +0100 |
|---|---|---|
| committer | Tom Christie | 2014-10-02 16:24:24 +0100 |
| commit | df7b6fcf58417fd95e49655eb140b387899b1ceb (patch) | |
| tree | a4a7d932bb3ef7c8e326b0248662fd31edcc2658 /rest_framework/renderers.py | |
| parent | ffc6aa3abcb0f823b43b63db1666913565e6f934 (diff) | |
| download | django-rest-framework-df7b6fcf58417fd95e49655eb140b387899b1ceb.tar.bz2 | |
First pass on incorperating the form rendering into the browsable API
Diffstat (limited to 'rest_framework/renderers.py')
| -rw-r--r-- | rest_framework/renderers.py | 62 |
1 files changed, 33 insertions, 29 deletions
diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index 297c60d8..931dd434 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -377,23 +377,21 @@ class HTMLFormRenderer(BaseRenderer): serializers.TimeField: 'time', }) - def render_field(self, field, value, errors, layout=None): + def render_field(self, field, layout=None): layout = layout or 'vertical' style_type = field.style.get('type', 'default') if style_type == 'textarea' and layout == 'inline': style_type = 'default' input_type = self.input_type[field] - if input_type == 'datetime-local': - value = value.rstrip('Z') + if input_type == 'datetime-local' and isinstance(field.value, six.text_type): + field.value = field.value.rstrip('Z') 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, 'input_type': input_type }) @@ -408,7 +406,7 @@ class HTMLFormRenderer(BaseRenderer): template = loader.get_template(self.template) context = RequestContext(request, { - 'form': data, + 'form': data.serializer, 'layout': getattr(getattr(data, 'Meta', None), 'layout', 'horizontal'), 'renderer': self }) @@ -479,27 +477,29 @@ class BrowsableAPIRenderer(BaseRenderer): return False # Doesn't have permissions return True - def get_rendered_html_form(self, view, method, request): + def get_rendered_html_form(self, data, view, method, request): """ Return a string representing a rendered HTML form, possibly bound to either the input or output data. In the absence of the View having an associated form then return None. """ + serializer = getattr(data, 'serializer', None) + if serializer and not getattr(serializer, 'many', False): + instance = getattr(serializer, 'instance', None) + else: + instance = None + if request.method == method: try: data = request.data - # files = request.FILES except ParseError: data = None - # files = None 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): + if not self.show_form_for_method(view, method, request, instance): return if method in ('DELETE', 'OPTIONS'): @@ -511,19 +511,24 @@ class BrowsableAPIRenderer(BaseRenderer): ): return - serializer = view.get_serializer(instance=obj, data=data) - serializer.is_valid() - data = serializer.data - + serializer = view.get_serializer(instance=instance, data=data) + if data is not None: + serializer.is_valid() form_renderer = self.form_renderer_class() - return form_renderer.render(data, self.accepted_media_type, self.renderer_context) + return form_renderer.render(serializer.data, self.accepted_media_type, self.renderer_context) - def get_raw_data_form(self, view, method, request): + def get_raw_data_form(self, data, view, method, request): """ Returns a form that allows for arbitrary content types to be tunneled via standard HTML forms. (Which are typically application/x-www-form-urlencoded) """ + serializer = getattr(data, 'serializer', None) + if serializer and not getattr(serializer, 'many', False): + instance = getattr(serializer, 'instance', None) + else: + instance = None + with override_method(view, request, method) as request: # If we're not using content overloading there's no point in # supplying a generic form, as the view won't treat the form's @@ -533,8 +538,7 @@ class BrowsableAPIRenderer(BaseRenderer): return None # Check permissions - obj = getattr(view, 'object', None) - if not self.show_form_for_method(view, method, request, obj): + if not self.show_form_for_method(view, method, request, instance): return # If possible, serialize the initial content for the generic form @@ -545,8 +549,8 @@ class BrowsableAPIRenderer(BaseRenderer): # corresponding renderer that can be used to render the data. # Get a read-only version of the serializer - serializer = view.get_serializer(instance=obj) - if obj is None: + serializer = view.get_serializer(instance=instance) + if instance is None: for name, field in serializer.fields.items(): if getattr(field, 'read_only', None): del serializer.fields[name] @@ -606,9 +610,9 @@ 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_post_form = self.get_raw_data_form(data, view, 'POST', request) + raw_data_put_form = self.get_raw_data_form(data, view, 'PUT', request) + raw_data_patch_form = self.get_raw_data_form(data, view, 'PATCH', request) raw_data_put_or_patch_form = raw_data_put_form or raw_data_patch_form response_headers = dict(response.items()) @@ -632,10 +636,10 @@ class BrowsableAPIRenderer(BaseRenderer): 'available_formats': [renderer_cls.format for renderer_cls in view.renderer_classes], 'response_headers': response_headers, - # 'put_form': self.get_rendered_html_form(view, 'PUT', request), - # 'post_form': self.get_rendered_html_form(view, 'POST', request), - # 'delete_form': self.get_rendered_html_form(view, 'DELETE', request), - # 'options_form': self.get_rendered_html_form(view, 'OPTIONS', request), + 'put_form': self.get_rendered_html_form(data, view, 'PUT', request), + 'post_form': self.get_rendered_html_form(data, view, 'POST', request), + 'delete_form': self.get_rendered_html_form(data, view, 'DELETE', request), + 'options_form': self.get_rendered_html_form(data, view, 'OPTIONS', request), 'raw_data_put_form': raw_data_put_form, 'raw_data_post_form': raw_data_post_form, |
