diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md index 614259458..89e956d26 100644 --- a/docs/api-guide/renderers.md +++ b/docs/api-guide/renderers.md @@ -197,9 +197,17 @@ Note that views that have nested or list serializers for their input won't work ## HTMLFormRenderer -Renders data returned by a serializer into an HTML form. The output of this renderer does not include the enclosing `
` tags or an submit actions, as you'll probably need those to include the desired method and URL. Also note that the `HTMLFormRenderer` does not yet support including field error messages. +Renders data returned by a serializer into an HTML form. The output of this renderer does not include the enclosing `` tags, a hidden CSRF input or any submit buttons. -**Note**: The `HTMLFormRenderer` class is intended for internal use with the browsable API and admin interface. It should not be considered a fully documented or stable API. The template used by the `HTMLFormRenderer` class, and the context submitted to it **may be subject to change**. If you need to use this renderer class it is advised that you either make a local copy of the class and templates, or follow the release note on REST framework upgrades closely. +This renderer is not intended to be used directly, but can instead be used in templates by passing a serializer instance to the `render_form` template tag. + + {% load rest_framework %} + + + {% csrf_token %} + {% render_form serializer %} + +
**.media_type**: `text/html` @@ -207,7 +215,7 @@ Renders data returned by a serializer into an HTML form. The output of this ren **.charset**: `utf-8` -**.template**: `'rest_framework/form.html'` +**.template**: `'rest_framework/horizontal/form.html'` ## MultiPartRenderer diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index c5b0aeb3c..2c44bd957 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -341,26 +341,16 @@ class HTMLFormRenderer(BaseRenderer): Render serializer data and return an HTML form, as a string. """ form = data.serializer - meta = getattr(form, 'Meta', None) - style = getattr(meta, 'style', {}) + + style = renderer_context.get('style', {}) if 'template_pack' not in style: style['template_pack'] = self.template_pack - if 'base_template' not in style: - style['base_template'] = self.base_template style['renderer'] = self - # This API needs to be finessed and finalized for 3.1 - if 'template' in renderer_context: - template_name = renderer_context['template'] - elif 'template' in style: - template_name = style['template'] - else: - template_name = style['template_pack'].strip('/') + '/' + style['base_template'] - - renderer_context = renderer_context or {} - request = renderer_context['request'] + template_pack = style['template_pack'].strip('/') + template_name = template_pack + '/' + self.base_template template = loader.get_template(template_name) - context = RequestContext(request, { + context = Context({ 'form': form, 'style': style }) @@ -505,10 +495,7 @@ class BrowsableAPIRenderer(BaseRenderer): return form_renderer.render( serializer.data, self.accepted_media_type, - dict( - list(self.renderer_context.items()) + - [('template', 'rest_framework/api_form.html')] - ) + self.renderer_context ) def get_raw_data_form(self, data, view, method, request): diff --git a/rest_framework/templates/rest_framework/api_form.html b/rest_framework/templates/rest_framework/api_form.html deleted file mode 100644 index 166988324..000000000 --- a/rest_framework/templates/rest_framework/api_form.html +++ /dev/null @@ -1,8 +0,0 @@ -{% load rest_framework %} -{% csrf_token %} -{% for field in form %} - {% if not field.read_only %} - {% render_field field style=style %} - {% endif %} -{% endfor %} - diff --git a/rest_framework/templates/rest_framework/base.html b/rest_framework/templates/rest_framework/base.html index 8d21487ee..220bb1d5a 100644 --- a/rest_framework/templates/rest_framework/base.html +++ b/rest_framework/templates/rest_framework/base.html @@ -154,6 +154,7 @@ {% with form=post_form %}
+ {% csrf_token %} {{ post_form }}
diff --git a/rest_framework/templates/rest_framework/horizontal/form.html b/rest_framework/templates/rest_framework/horizontal/form.html index af16a0eb4..13fc807eb 100644 --- a/rest_framework/templates/rest_framework/horizontal/form.html +++ b/rest_framework/templates/rest_framework/horizontal/form.html @@ -1,16 +1,6 @@ {% load rest_framework %} - - - {% csrf_token %} - {% for field in form %} - {% if not field.read_only %} - {% render_field field style=style %} - {% endif %} - {% endfor %} - -
-
- -
-
- +{% for field in form %} + {% if not field.read_only %} + {% render_field field style=style %} + {% endif %} +{% endfor %} diff --git a/rest_framework/templates/rest_framework/inline/form.html b/rest_framework/templates/rest_framework/inline/form.html index e56e4312b..13fc807eb 100644 --- a/rest_framework/templates/rest_framework/inline/form.html +++ b/rest_framework/templates/rest_framework/inline/form.html @@ -1,13 +1,6 @@ {% load rest_framework %} - -
- {% csrf_token %} - - {% for field in form %} - {% if not field.read_only %} - {% render_field field style=style %} - {% endif %} - {% endfor %} - - -
+{% for field in form %} + {% if not field.read_only %} + {% render_field field style=style %} + {% endif %} +{% endfor %} diff --git a/rest_framework/templates/rest_framework/vertical/form.html b/rest_framework/templates/rest_framework/vertical/form.html index bd57ca19a..13fc807eb 100644 --- a/rest_framework/templates/rest_framework/vertical/form.html +++ b/rest_framework/templates/rest_framework/vertical/form.html @@ -1,12 +1,6 @@ {% load rest_framework %} - -
- {% csrf_token %} - {% for field in form %} - {% if not field.read_only %} - {% render_field field style=style %} - {% endif %} - {% endfor %} - - -
+{% for field in form %} + {% if not field.read_only %} + {% render_field field style=style %} + {% endif %} +{% endfor %} diff --git a/rest_framework/templatetags/rest_framework.py b/rest_framework/templatetags/rest_framework.py index 08acecef7..b584fdbaf 100644 --- a/rest_framework/templatetags/rest_framework.py +++ b/rest_framework/templatetags/rest_framework.py @@ -25,8 +25,14 @@ def get_pagination_html(pager): @register.simple_tag -def render_field(field, style=None): - style = style or {} +def render_form(serializer, template_pack=None): + style = {'template_pack': template_pack} if template_pack else {} + renderer = HTMLFormRenderer() + return renderer.render(serializer.data, None, {'style': style}) + + +@register.simple_tag +def render_field(field, style): renderer = style.get('renderer', HTMLFormRenderer()) return renderer.render_field(field, style)