diff options
| author | Tom Christie | 2013-02-20 12:18:57 +0000 | 
|---|---|---|
| committer | Tom Christie | 2013-02-20 12:18:57 +0000 | 
| commit | 03afaee423967e09fe266e9fe124f661c1e10ccb (patch) | |
| tree | 22cb4f529d34cdd60ec860ef73255d0293d14d00 /rest_framework | |
| parent | 47a4f0863d08e4b839ea3bbd7308ecc0f995b7d9 (diff) | |
| parent | 2fb6fa2dd3b336cc442e707dbb80a4d5616582a6 (diff) | |
| download | django-rest-framework-03afaee423967e09fe266e9fe124f661c1e10ccb.tar.bz2 | |
Merge branch 'browsable_api_patch' of https://github.com/wronglink/django-rest-framework into generic-form-input
Diffstat (limited to 'rest_framework')
| -rw-r--r-- | rest_framework/renderers.py | 10 | ||||
| -rw-r--r-- | rest_framework/static/rest_framework/css/default.css | 11 | ||||
| -rw-r--r-- | rest_framework/static/rest_framework/js/default.js | 2 | ||||
| -rw-r--r-- | rest_framework/templates/rest_framework/base.html | 116 | ||||
| -rw-r--r-- | rest_framework/templates/rest_framework/form.html | 13 | ||||
| -rw-r--r-- | rest_framework/tests/renderers.py | 4 | ||||
| -rw-r--r-- | rest_framework/tests/utils.py | 16 | 
7 files changed, 125 insertions, 47 deletions
diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index a6525404..736384d6 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -345,12 +345,11 @@ class BrowsableAPIRenderer(BaseRenderer):          if not self.show_form_for_method(view, method, request, obj):              return -        if method == 'DELETE' or method == 'OPTIONS': +        if method in ('DELETE', 'OPTIONS'):              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: -            media_types = [parser.media_type for parser in view.parser_classes] -            return self.get_generic_content_form(media_types) +            return          serializer = view.get_serializer(instance=obj)          fields = self.serializer_to_form_fields(serializer) @@ -422,14 +421,17 @@ class BrowsableAPIRenderer(BaseRenderer):          view = renderer_context['view']          request = renderer_context['request']          response = renderer_context['response'] +        media_types = [parser.media_type for parser in view.parser_classes]          renderer = self.get_default_renderer(view)          content = self.get_content(renderer, data, accepted_media_type, renderer_context)          put_form = self.get_form(view, 'PUT', 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)          options_form = self.get_form(view, 'OPTIONS', request) +        generic_content_form = self.get_generic_content_form(media_types)          name = self.get_name(view)          description = self.get_description(view) @@ -449,8 +451,10 @@ class BrowsableAPIRenderer(BaseRenderer):              '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,              '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 b2e41b99..73107527 100644 --- a/rest_framework/static/rest_framework/css/default.css +++ b/rest_framework/static/rest_framework/css/default.css @@ -150,6 +150,17 @@ html, body {    margin: 0 auto -60px;  } +.form-switcher { +    margin-bottom: 0; +} + +.tab-content { +    padding-top: 25px; +    background: #fff; +    border: 1px solid #ddd; +    border-top: none; +    border-radius: 0 0 4px 4px; +}  #footer, #push {    height: 60px; /* .push must be the same height as .footer */ diff --git a/rest_framework/static/rest_framework/js/default.js b/rest_framework/static/rest_framework/js/default.js index ecaccc0f..484a3bdf 100644 --- a/rest_framework/static/rest_framework/js/default.js +++ b/rest_framework/static/rest_framework/js/default.js @@ -3,3 +3,5 @@ prettyPrint();  $('.js-tooltip').tooltip({      delay: 1000  }); + +$('.form-switcher a:first').tab('show');
\ No newline at end of file diff --git a/rest_framework/templates/rest_framework/base.html b/rest_framework/templates/rest_framework/base.html index 8d807574..2fe7b653 100644 --- a/rest_framework/templates/rest_framework/base.html +++ b/rest_framework/templates/rest_framework/base.html @@ -125,54 +125,86 @@                  {% if post_form %}                  <div class="well"> -                    <form action="{{ request.get_full_path }}" method="POST" {% if post_form.is_multipart %}enctype="multipart/form-data"{% endif %} class="form-horizontal"> -                        <fieldset> -                            {% csrf_token %} -                            {{ post_form.non_field_errors }} -                            {% for field in post_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 %} -                            <div class="form-actions"> -                                <button class="btn btn-primary" title="Make a POST request on the {{ name }} resource">POST</button> -                            </div> -                        </fieldset> -                    </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> +                    </ul> +                    <div class="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> +                            {% 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> +                            {% endwith %} +                        </div> +                    </div>                  </div>                  {% endif %} -                {% if put_form %} +                {% if 'PUT' in allowed_methods or 'PATCH' in allowed_methods %}                  <div class="well"> -                    <form action="{{ request.get_full_path }}" method="POST" {% if put_form.is_multipart %}enctype="multipart/form-data"{% endif %} class="form-horizontal"> -                        <fieldset> -                            <input type="hidden" name="{{ api_settings.FORM_METHOD_OVERRIDE }}" value="PUT" /> -                            {% csrf_token %} -                            {{ put_form.non_field_errors }} -                            {% for field in put_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 %} -                            <div class="form-actions"> -                                <button class="btn btn-primary js-tooltip" title="Make a PUT request on the {{ name }} resource">PUT</button> -                            </div> - -                        </fieldset> -                    </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> +                    </ul> +                    <div class="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> +                            {% 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> +                            {% endwith %} +                        </div> +                    </div>                  </div>                  {% endif %} -              {% endif %}          </div> diff --git a/rest_framework/templates/rest_framework/form.html b/rest_framework/templates/rest_framework/form.html new file mode 100644 index 00000000..dc7acc70 --- /dev/null +++ b/rest_framework/templates/rest_framework/form.html @@ -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 %} diff --git a/rest_framework/tests/renderers.py b/rest_framework/tests/renderers.py index e3f45ce6..90ef1221 100644 --- a/rest_framework/tests/renderers.py +++ b/rest_framework/tests/renderers.py @@ -112,6 +112,9 @@ class POSTDeniedView(APIView):      def put(self, request):          return Response() +    def patch(self, request): +        return Response() +  class DocumentingRendererTests(TestCase):      def test_only_permitted_forms_are_displayed(self): @@ -120,6 +123,7 @@ class DocumentingRendererTests(TestCase):          response = view(request).render()          self.assertNotContains(response, '>POST<')          self.assertContains(response, '>PUT<') +        self.assertContains(response, '>PATCH<')  class RendererEndToEndTests(TestCase): diff --git a/rest_framework/tests/utils.py b/rest_framework/tests/utils.py index 224c4f9d..8c87917d 100644 --- a/rest_framework/tests/utils.py +++ b/rest_framework/tests/utils.py @@ -1,10 +1,10 @@  from __future__ import unicode_literals -from django.test.client import RequestFactory, FakePayload +from django.test.client import FakePayload, Client as _Client, RequestFactory as _RequestFactory  from django.test.client import MULTIPART_CONTENT  from rest_framework.compat import urlparse -class RequestFactory(RequestFactory): +class RequestFactory(_RequestFactory):      def __init__(self, **defaults):          super(RequestFactory, self).__init__(**defaults) @@ -26,3 +26,15 @@ class RequestFactory(RequestFactory):          }          r.update(extra)          return self.request(**r) + + +class Client(_Client, RequestFactory): +    def patch(self, path, data={}, content_type=MULTIPART_CONTENT, +              follow=False, **extra): +        """ +        Send a resource to the server using PATCH. +        """ +        response = super(Client, self).patch(path, data=data, content_type=content_type, **extra) +        if follow: +            response = self._handle_redirects(response, **extra) +        return response  | 
