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
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`
@ -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

View File

@ -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):

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 %}
<form action="{{ request.get_full_path }}" method="POST" enctype="multipart/form-data" class="form-horizontal" novalidate>
<fieldset>
{% csrf_token %}
{{ post_form }}
<div class="form-actions">
<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 %}
<form class="form-horizontal" role="form" action="." method="POST" novalidate>
{% csrf_token %}
{% for field in form %}
{% if not field.read_only %}
{% 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>
{% for field in form %}
{% if not field.read_only %}
{% render_field field style=style %}
{% endif %}
{% endfor %}

View File

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

View File

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

View File

@ -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)