From 580031a9149f29fdd96674f22b83e3124877b7a7 Mon Sep 17 00:00:00 2001 From: "Sean C. Farley" Date: Mon, 9 Apr 2012 14:28:04 -0400 Subject: [PATCH 1/2] Add GET method form handling Add handling of forms for the GET method. The code requires the form for the GET method to be explicitly declared (e.g., get_form = AGetForm); the form attribute will only be used for POST and PUT but not GET. --- djangorestframework/renderers.py | 8 ++++++-- djangorestframework/resources.py | 10 +++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/djangorestframework/renderers.py b/djangorestframework/renderers.py index d9aa4028e..e40865b62 100644 --- a/djangorestframework/renderers.py +++ b/djangorestframework/renderers.py @@ -251,8 +251,10 @@ class DocumentingTemplateRenderer(BaseRenderer): except Exception: pass - # If we still don't have a form instance then try to get an unbound form which can tunnel arbitrary content types - if not form_instance: + # If we still don't have a form instance then try to get an unbound form + # which can tunnel arbitrary content types. Forms for the GET method + # must be explicit, so do not create a generic form. + if not form_instance and method != 'get': form_instance = self._get_generic_content_form(view) return form_instance @@ -316,6 +318,7 @@ class DocumentingTemplateRenderer(BaseRenderer): content = self._get_content(self.view, self.view.request, obj, media_type) + get_form_instance = self._get_form_instance(self.view, 'get') put_form_instance = self._get_form_instance(self.view, 'put') post_form_instance = self._get_form_instance(self.view, 'post') @@ -342,6 +345,7 @@ class DocumentingTemplateRenderer(BaseRenderer): 'version': VERSION, 'breadcrumblist': breadcrumb_list, 'available_formats': self.view._rendered_formats, + 'get_form': get_form_instance, 'put_form': put_form_instance, 'post_form': post_form_instance, 'FORMAT_PARAM': self._FORMAT_QUERY_PARAM, diff --git a/djangorestframework/resources.py b/djangorestframework/resources.py index f170eb45a..a4ca8a508 100644 --- a/djangorestframework/resources.py +++ b/djangorestframework/resources.py @@ -182,15 +182,19 @@ class FormResource(Resource): """ Returns the form class used to validate this resource. """ - # A form on the view overrides a form on the resource. - form = getattr(self.view, 'form', None) or self.form - # Use the requested method or determine the request method if method is None and hasattr(self.view, 'request') and hasattr(self.view, 'method'): method = self.view.method elif method is None and hasattr(self.view, 'request'): method = self.view.request.method + # A form on the view overrides a form on the resource. The GET method + # must have its form explicity set (e.g., get_form). + if not method or method.lower() != 'get': + form = getattr(self.view, 'form', None) or self.form + else: + form = None + # A method form on the view or resource overrides the general case. # Method forms are attributes like `get_form` `post_form` `put_form`. if method: From b5f986abddad0d3559052c63761ec3d0a68ab4f8 Mon Sep 17 00:00:00 2001 From: "Sean C. Farley" Date: Tue, 10 Apr 2012 12:23:06 -0400 Subject: [PATCH 2/2] Avoid unbound form for GET instance Do not attempt to get an unbound form for an instance using a GET method. This results in the same issue as getting a generic form where an explicit form must be provided for an instance obtained using the GET method. --- djangorestframework/renderers.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/djangorestframework/renderers.py b/djangorestframework/renderers.py index e40865b62..a72ebaf11 100644 --- a/djangorestframework/renderers.py +++ b/djangorestframework/renderers.py @@ -244,18 +244,20 @@ class DocumentingTemplateRenderer(BaseRenderer): except Exception: form_instance = None - # If we still don't have a form instance then try to get an unbound form - if not form_instance: - try: - form_instance = view.get_bound_form(method=method) - except Exception: - pass + # Forms for the GET method must be explicit, so do not get an unbound + # form nor create a generic form for this instance. + if method != 'get': + # If we still don't have a form instance then try to get an unbound form + if not form_instance: + try: + form_instance = view.get_bound_form(method=method) + except Exception: + pass - # If we still don't have a form instance then try to get an unbound form - # which can tunnel arbitrary content types. Forms for the GET method - # must be explicit, so do not create a generic form. - if not form_instance and method != 'get': - form_instance = self._get_generic_content_form(view) + # If we still don't have a form instance then try to get an unbound form + # which can tunnel arbitrary content types. + if not form_instance: + form_instance = self._get_generic_content_form(view) return form_instance