aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--rest_framework/renderers.py23
-rw-r--r--rest_framework/static/rest_framework/css/default.css43
-rw-r--r--rest_framework/templates/rest_framework/base.html110
3 files changed, 111 insertions, 65 deletions
diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py
index 736384d6..637904c4 100644
--- a/rest_framework/renderers.py
+++ b/rest_framework/renderers.py
@@ -361,7 +361,7 @@ class BrowsableAPIRenderer(BaseRenderer):
form_instance = OnTheFlyForm(data)
return form_instance
- def get_generic_content_form(self, media_types):
+ def get_raw_data_form(self, view, method, request, media_types):
"""
Returns a form that allows for arbitrary content types to be tunneled
via standard HTML forms.
@@ -374,6 +374,11 @@ class BrowsableAPIRenderer(BaseRenderer):
and api_settings.FORM_CONTENTTYPE_OVERRIDE):
return None
+ # Check permissions
+ obj = getattr(view, 'object', None)
+ if not self.show_form_for_method(view, method, request, obj):
+ return
+
content_type_field = api_settings.FORM_CONTENTTYPE_OVERRIDE
content_field = api_settings.FORM_CONTENT_OVERRIDE
choices = [(media_type, media_type) for media_type in media_types]
@@ -385,7 +390,7 @@ class BrowsableAPIRenderer(BaseRenderer):
super(GenericContentForm, self).__init__()
self.fields[content_type_field] = forms.ChoiceField(
- label='Content Type',
+ label='Media type',
choices=choices,
initial=initial
)
@@ -431,7 +436,11 @@ class BrowsableAPIRenderer(BaseRenderer):
patch_form = self.get_form(view, 'PATCH', request)
delete_form = self.get_form(view, 'DELETE', request)
options_form = self.get_form(view, 'OPTIONS', request)
- generic_content_form = self.get_generic_content_form(media_types)
+
+ raw_data_put_form = self.get_raw_data_form(view, 'PUT', request, media_types)
+ raw_data_post_form = self.get_raw_data_form(view, 'POST', request, media_types)
+ raw_data_patch_form = self.get_raw_data_form(view, 'PATCH', request, media_types)
+ raw_data_put_or_patch_form = raw_data_put_form or raw_data_patch_form
name = self.get_name(view)
description = self.get_description(view)
@@ -449,12 +458,18 @@ class BrowsableAPIRenderer(BaseRenderer):
'breadcrumblist': breadcrumb_list,
'allowed_methods': view.allowed_methods,
'available_formats': [renderer.format for renderer in view.renderer_classes],
+
'put_form': put_form,
'post_form': post_form,
'patch_form': patch_form,
'delete_form': delete_form,
'options_form': options_form,
- 'generic_content_form': generic_content_form,
+
+ 'raw_data_put_form': raw_data_put_form,
+ 'raw_data_post_form': raw_data_post_form,
+ 'raw_data_patch_form': raw_data_patch_form,
+ 'raw_data_put_or_patch_form': raw_data_put_or_patch_form,
+
'api_settings': api_settings
})
diff --git a/rest_framework/static/rest_framework/css/default.css b/rest_framework/static/rest_framework/css/default.css
index 73107527..4e7cbc06 100644
--- a/rest_framework/static/rest_framework/css/default.css
+++ b/rest_framework/static/rest_framework/css/default.css
@@ -154,12 +154,43 @@ html, body {
margin-bottom: 0;
}
-.tab-content {
- padding-top: 25px;
- background: #fff;
- border: 1px solid #ddd;
- border-top: none;
- border-radius: 0 0 4px 4px;
+.well .form-actions {
+ padding-bottom: 0;
+ margin-bottom: 0;
+}
+
+.well form {
+ margin-bottom: 0;
+}
+
+.nav-tabs {
+ border: 0;
+}
+
+.nav-tabs > li {
+ margin-bottom: -3px;
+ float: right;
+}
+
+.nav-tabs li a {
+ margin-right: 0;
+}
+
+.nav-tabs > .active > a {
+ background: #f5f5f5;
+}
+
+.nav-tabs > .active > a:hover {
+ background: #f5f5f5;
+}
+
+.tabs-below > .nav-tabs {
+ border-bottom: none !important;
+}
+
+.tabs-below > .nav-tabs > li {
+ margin-bottom: -2px !important;
+ margin-right: 0 !important;
}
#footer, #push {
diff --git a/rest_framework/templates/rest_framework/base.html b/rest_framework/templates/rest_framework/base.html
index 2fe7b653..44633f5a 100644
--- a/rest_framework/templates/rest_framework/base.html
+++ b/rest_framework/templates/rest_framework/base.html
@@ -123,83 +123,83 @@
{% if response.status_code != 403 %}
- {% if post_form %}
- <div class="well">
+ {% if post_form or raw_data_post_form %}
+ <div {% if post_form %}class="tabbable"{% endif %}>
+ {% if post_form %}
<ul class="nav nav-tabs form-switcher">
- {% if post_form %}
- <li><a href="#object-form" data-toggle="tab">HTML</a></li>
- {% endif %}
- <li><a href="#generic-content-form" data-toggle="tab">Generic content</a></li>
+ <li><a href="#object-form" data-toggle="tab">HTML form</a></li>
+ <li><a href="#generic-content-form" data-toggle="tab">Raw data</a></li>
</ul>
- <div class="tab-content">
+ {% endif %}
+ <div class="well tab-content">
{% if post_form %}
<div class="tab-pane" id="object-form">
{% with form=post_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">
- <button class="btn btn-primary" title="Make a POST request on the {{ name }} resource">POST</button>
- </div>
- </fieldset>
- </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">
+ <button class="btn btn-primary" title="Make a POST request on the {{ name }} resource">POST</button>
+ </div>
+ </fieldset>
+ </form>
{% endwith %}
</div>
{% 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">
- <button class="btn btn-primary" title="Make a POST request on the {{ name }} resource">POST</button>
- </div>
- </fieldset>
- </form>
+ <div {% if post_form %}class="tab-pane"{% endif %} id="generic-content-form">
+ {% with form=raw_data_post_form %}
+ <form action="{{ request.get_full_path }}" method="POST" class="form-horizontal">
+ <fieldset>
+ {% include "rest_framework/form.html" %}
+ <div class="form-actions">
+ <button class="btn btn-primary" title="Make a POST request on the {{ name }} resource">POST</button>
+ </div>
+ </fieldset>
+ </form>
{% endwith %}
</div>
</div>
</div>
{% endif %}
- {% if 'PUT' in allowed_methods or 'PATCH' in allowed_methods %}
- <div class="well">
+ {% if put_form or raw_data_put_form or raw_data_patch_form %}
+ <div {% if put_form %}class="tabbable"{% endif %}>
+ {% if put_form %}
<ul class="nav nav-tabs form-switcher">
- {% if put_form %}
- <li><a href="#object-form" data-toggle="tab">HTML</a></li>
- {% endif %}
- <li><a href="#generic-content-form" data-toggle="tab">Generic content</a></li>
+ <li><a href="#object-form" data-toggle="tab">HTML form</a></li>
+ <li><a href="#generic-content-form" data-toggle="tab">Raw data</a></li>
</ul>
- <div class="tab-content">
+ {% endif %}
+ <div class="well tab-content">
{% if put_form %}
<div class="tab-pane" id="object-form">
{% with form=put_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">
- <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>
- </fieldset>
- </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">
+ <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>
+ </fieldset>
+ </form>
{% endwith %}
</div>
{% 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>
+ <div {% if put_form %}class="tab-pane"{% endif %} id="generic-content-form">
+ {% with form=raw_data_put_or_patch_form %}
+ <form action="{{ request.get_full_path }}" method="POST" class="form-horizontal">
+ <fieldset>
+ {% include "rest_framework/form.html" %}
+ <div class="form-actions">
+ {% if raw_data_put_form %}
+ <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 raw_data_patch_form %}
+ <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>