Formns API

This commit is contained in:
Tom Christie 2015-10-06 10:58:20 +01:00
parent 63662e352d
commit 41182c6f06
8 changed files with 41 additions and 70 deletions

View File

@ -197,9 +197,17 @@ Note that views that have nested or list serializers for their input won't work
## HTMLFormRenderer ## HTMLFormRenderer
Renders data returned by a serializer into an HTML form. The output of this renderer does not include the enclosing `<form>` 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 `<form>` 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 %}
<form action="/submit-report/" method="post">
{% csrf_token %}
{% render_form serializer %}
<input type="submit" value="Save" />
</form>
**.media_type**: `text/html` **.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` **.charset**: `utf-8`
**.template**: `'rest_framework/form.html'` **.template**: `'rest_framework/horizontal/form.html'`
## MultiPartRenderer ## MultiPartRenderer

View File

@ -341,26 +341,16 @@ class HTMLFormRenderer(BaseRenderer):
Render serializer data and return an HTML form, as a string. Render serializer data and return an HTML form, as a string.
""" """
form = data.serializer form = data.serializer
meta = getattr(form, 'Meta', None)
style = getattr(meta, 'style', {}) style = renderer_context.get('style', {})
if 'template_pack' not in style: if 'template_pack' not in style:
style['template_pack'] = self.template_pack style['template_pack'] = self.template_pack
if 'base_template' not in style:
style['base_template'] = self.base_template
style['renderer'] = self style['renderer'] = self
# This API needs to be finessed and finalized for 3.1 template_pack = style['template_pack'].strip('/')
if 'template' in renderer_context: template_name = template_pack + '/' + self.base_template
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 = loader.get_template(template_name) template = loader.get_template(template_name)
context = RequestContext(request, { context = Context({
'form': form, 'form': form,
'style': style 'style': style
}) })
@ -505,10 +495,7 @@ class BrowsableAPIRenderer(BaseRenderer):
return form_renderer.render( return form_renderer.render(
serializer.data, serializer.data,
self.accepted_media_type, self.accepted_media_type,
dict( self.renderer_context
list(self.renderer_context.items()) +
[('template', 'rest_framework/api_form.html')]
)
) )
def get_raw_data_form(self, data, view, method, request): def get_raw_data_form(self, data, view, method, request):

View File

@ -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 %}
<!-- form.non_field_errors -->

View File

@ -154,6 +154,7 @@
{% with form=post_form %} {% with form=post_form %}
<form action="{{ request.get_full_path }}" method="POST" enctype="multipart/form-data" class="form-horizontal" novalidate> <form action="{{ request.get_full_path }}" method="POST" enctype="multipart/form-data" class="form-horizontal" novalidate>
<fieldset> <fieldset>
{% csrf_token %}
{{ post_form }} {{ post_form }}
<div class="form-actions"> <div class="form-actions">
<button class="btn btn-primary" title="Make a POST request on the {{ name }} resource">POST</button> <button class="btn btn-primary" title="Make a POST request on the {{ name }} resource">POST</button>

View File

@ -1,16 +1,6 @@
{% load rest_framework %} {% load rest_framework %}
{% for field in form %}
<form class="form-horizontal" role="form" action="." method="POST" novalidate> {% if not field.read_only %}
{% csrf_token %} {% render_field field style=style %}
{% for field in form %} {% endif %}
{% if not field.read_only %} {% endfor %}
{% render_field field style=style %}
{% endif %}
{% endfor %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Submit</button>
</div>
</div>
</form>

View File

@ -1,13 +1,6 @@
{% load rest_framework %} {% load rest_framework %}
{% for field in form %}
<form class="form-inline" role="form" action="." method="POST" novalidate> {% if not field.read_only %}
{% csrf_token %} {% render_field field style=style %}
{% endif %}
{% for field in form %} {% endfor %}
{% if not field.read_only %}
{% render_field field style=style %}
{% endif %}
{% endfor %}
<button type="submit" class="btn btn-default">Submit</button>
</form>

View File

@ -1,12 +1,6 @@
{% load rest_framework %} {% load rest_framework %}
{% for field in form %}
<form role="form" action="." method="POST" novalidate> {% if not field.read_only %}
{% csrf_token %} {% render_field field style=style %}
{% for field in form %} {% endif %}
{% if not field.read_only %} {% endfor %}
{% render_field field style=style %}
{% endif %}
{% endfor %}
<button type="submit" class="btn btn-default">Submit</button>
</form>

View File

@ -25,8 +25,14 @@ def get_pagination_html(pager):
@register.simple_tag @register.simple_tag
def render_field(field, style=None): def render_form(serializer, template_pack=None):
style = style or {} 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()) renderer = style.get('renderer', HTMLFormRenderer())
return renderer.render_field(field, style) return renderer.render_field(field, style)