Added tabs between object form and generic content form on PUT/PATCH form

Some extra behaviour to `BrowsableAPIRenderer` to handle PATCH form.
Added PATCH button on generic content PUT form.
Tabs between object form and generic content form on PUT/PATCH form wich are
both allways visible now.

Fix #570
Refs #591
This commit is contained in:
Michael Elovskikh 2013-02-15 14:41:12 +06:00
parent de029561d0
commit 8fdf925015
4 changed files with 62 additions and 26 deletions

View File

@ -345,12 +345,11 @@ class BrowsableAPIRenderer(BaseRenderer):
if not self.show_form_for_method(view, method, request, obj): if not self.show_form_for_method(view, method, request, obj):
return return
if method == 'DELETE' or method == 'OPTIONS': if method in ('DELETE', 'OPTIONS'):
return True # Don't actually need to return a form return True # Don't actually need to return a form
if not getattr(view, 'get_serializer', None) or not parsers.FormParser in view.parser_classes: if not getattr(view, 'get_serializer', None) or not parsers.FormParser in view.parser_classes:
media_types = [parser.media_type for parser in view.parser_classes] return
return self.get_generic_content_form(media_types)
serializer = view.get_serializer(instance=obj) serializer = view.get_serializer(instance=obj)
fields = self.serializer_to_form_fields(serializer) fields = self.serializer_to_form_fields(serializer)
@ -422,14 +421,17 @@ class BrowsableAPIRenderer(BaseRenderer):
view = renderer_context['view'] view = renderer_context['view']
request = renderer_context['request'] request = renderer_context['request']
response = renderer_context['response'] response = renderer_context['response']
media_types = [parser.media_type for parser in view.parser_classes]
renderer = self.get_default_renderer(view) renderer = self.get_default_renderer(view)
content = self.get_content(renderer, data, accepted_media_type, renderer_context) content = self.get_content(renderer, data, accepted_media_type, renderer_context)
put_form = self.get_form(view, 'PUT', request) put_form = self.get_form(view, 'PUT', request)
post_form = self.get_form(view, 'POST', request) post_form = self.get_form(view, 'POST', request)
patch_form = self.get_form(view, 'PATCH', request)
delete_form = self.get_form(view, 'DELETE', request) delete_form = self.get_form(view, 'DELETE', request)
options_form = self.get_form(view, 'OPTIONS', request) options_form = self.get_form(view, 'OPTIONS', request)
generic_content_form = self.get_generic_content_form(media_types)
name = self.get_name(view) name = self.get_name(view)
description = self.get_description(view) description = self.get_description(view)
@ -449,8 +451,10 @@ class BrowsableAPIRenderer(BaseRenderer):
'available_formats': [renderer.format for renderer in view.renderer_classes], 'available_formats': [renderer.format for renderer in view.renderer_classes],
'put_form': put_form, 'put_form': put_form,
'post_form': post_form, 'post_form': post_form,
'patch_form': patch_form,
'delete_form': delete_form, 'delete_form': delete_form,
'options_form': options_form, 'options_form': options_form,
'generic_content_form': generic_content_form,
'api_settings': api_settings 'api_settings': api_settings
}) })

View File

@ -3,3 +3,5 @@ prettyPrint();
$('.js-tooltip').tooltip({ $('.js-tooltip').tooltip({
delay: 1000 delay: 1000
}); });
$('#form-switcher a:first').tab('show');

View File

@ -147,32 +147,49 @@
</div> </div>
{% endif %} {% endif %}
{% if put_form %} {% if 'PUT' in allowed_methods or 'PATCH' in allowed_methods %}
<div class="well"> <div class="well">
<form action="{{ request.get_full_path }}" method="POST" {% if put_form.is_multipart %}enctype="multipart/form-data"{% endif %} class="form-horizontal"> <ul class="nav nav-pills" id="form-switcher">
<fieldset> {% if put_form %}
<input type="hidden" name="{{ api_settings.FORM_METHOD_OVERRIDE }}" value="PUT" /> <li><a href="#object-form" data-toggle="pill">Object form</a></li>
{% csrf_token %} {% endif %}
{{ put_form.non_field_errors }} <li><a href="#generic-content-form" data-toggle="pill">Generic content form</a></li>
{% for field in put_form %} </ul>
<div class="control-group"> <!--{% if field.errors %}error{% endif %}--> <div class="tab-content">
{{ field.label_tag|add_class:"control-label" }} {% if put_form %}
<div class="controls"> <div class="tab-pane" id="object-form">
{{ field }} {% with form=put_form %}
<span class='help-inline'>{{ field.help_text }}</span> <form action="{{ request.get_full_path }}" method="POST" {% if form.is_multipart %}enctype="multipart/form-data"{% endif %} class="form-horizontal">
<!--{{ field.errors|add_class:"help-block" }}--> <fieldset>
</div> {% include "rest_framework/form.html" %}
</div> <div class="form-actions">
{% endfor %} <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>
<div class="form-actions"> </div>
<button class="btn btn-primary js-tooltip" title="Make a PUT request on the {{ name }} resource">PUT</button> </fieldset>
</div> </form>
{% endwith %}
</fieldset> </div>
</form> {% endif %}
<div class="tab-pane" id="generic-content-form">
{% with form=generic_content_form %}
<form action="{{ request.get_full_path }}" method="POST" {% if form.is_multipart %}enctype="multipart/form-data"{% endif %} class="form-horizontal">
<fieldset>
{% include "rest_framework/form.html" %}
<div class="form-actions">
{% if 'PUT' in allowed_methods %}
<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>
{% endif %}
{% if 'PATCH' in allowed_methods %}
<button class="btn btn-primary js-tooltip" name="{{ api_settings.FORM_METHOD_OVERRIDE }}" value="PATCH" title="Make a PUT request on the {{ name }} resource">PATCH</button>
{% endif %}
</div>
</fieldset>
</form>
{% endwith %}
</div>
</div>
</div> </div>
{% endif %} {% endif %}
{% endif %} {% endif %}
</div> </div>

View File

@ -0,0 +1,13 @@
{% load rest_framework %}
{% csrf_token %}
{{ form.non_field_errors }}
{% for field in form %}
<div class="control-group"> <!--{% if field.errors %}error{% endif %}-->
{{ field.label_tag|add_class:"control-label" }}
<div class="controls">
{{ field }}
<span class="help-inline">{{ field.help_text }}</span>
<!--{{ field.errors|add_class:"help-block" }}-->
</div>
</div>
{% endfor %}