From 024780a974eed66a45f27f27cfbec28bd1432d07 Mon Sep 17 00:00:00 2001 From: Marko Tibold Date: Sat, 8 Sep 2012 18:18:05 +0200 Subject: [PATCH 1/4] Fields are showing up again. Still WIP. --- djangorestframework/renderers.py | 41 ++++++++----------- .../templates/djangorestframework/base.html | 5 +-- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/djangorestframework/renderers.py b/djangorestframework/renderers.py index 4f8225b12..4a14d5ee8 100644 --- a/djangorestframework/renderers.py +++ b/djangorestframework/renderers.py @@ -16,6 +16,7 @@ from djangorestframework.utils import encoders from djangorestframework.utils.breadcrumbs import get_breadcrumbs from djangorestframework.utils.mediatypes import get_media_type_params, add_media_type_param, media_type_matches from djangorestframework import VERSION +from djangorestframework.fields import FloatField, IntegerField, DateTimeField, DateField, EmailField, CharField, BooleanField import string @@ -234,32 +235,24 @@ class DocumentingTemplateRenderer(BaseRenderer): provide a form that can be used to submit arbitrary content. """ - # Get the form instance if we have one bound to the input - form_instance = None - if method == getattr(view, 'method', view.request.method).lower(): - form_instance = getattr(view, 'bound_form_instance', None) + # We need to map our Fields to Django's Fields. + field_mapping = dict([ + [FloatField.__name__, forms.FloatField], + [IntegerField.__name__, forms.IntegerField], + [DateTimeField.__name__, forms.DateTimeField], + [DateField.__name__, forms.DateField], + [EmailField.__name__, forms.EmailField], + [CharField.__name__, forms.CharField], + [BooleanField.__name__, forms.BooleanField] + ]) - if not form_instance and hasattr(view, 'get_bound_form'): - # Otherwise if we have a response that is valid against the form then use that - if view.response.has_content_body: - try: - form_instance = view.get_bound_form(view.response.cleaned_content, method=method) - if form_instance and not form_instance.is_valid(): - form_instance = None - 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 - - # 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) + # Creating an on the fly form see: http://stackoverflow.com/questions/3915024/dynamically-creating-classes-python + fields = {} + for k, v in self.view.get_serializer().fields.items(): + fields[k] = field_mapping[v.__class__.__name__]() + OnTheFlyForm = type("OnTheFlyForm", (forms.Form,), fields) + form_instance = OnTheFlyForm(self.view.get_serializer().data) return form_instance def _get_generic_content_form(self, view): diff --git a/djangorestframework/templates/djangorestframework/base.html b/djangorestframework/templates/djangorestframework/base.html index d33c53930..97e81bbed 100644 --- a/djangorestframework/templates/djangorestframework/base.html +++ b/djangorestframework/templates/djangorestframework/base.html @@ -78,8 +78,6 @@ {% endif %} - {% comment %} - DROP POST/PUT/DELETE until the forms are working with REST framework 2 {# Only display the POST/PUT/DELETE forms if method tunneling via POST forms is enabled and the user has permissions on this view. #} {% if response.status_code != 403 %} @@ -90,7 +88,7 @@

POST {{ name }}

{% csrf_token %} {{ post_form.non_field_errors }} - {% for field in post_form %} + {% for field in post_form %}
{{ field.label_tag }} {{ field }} @@ -141,7 +139,6 @@ {% endif %} {% endif %} - {% endcomment %}
From 55f7dd9bcede90d6c5596e357035007b26a98dba Mon Sep 17 00:00:00 2001 From: Marko Tibold Date: Sat, 8 Sep 2012 21:56:18 +0200 Subject: [PATCH 2/4] `error_data` -> `errors` Prefill form for instance view. --- djangorestframework/mixins.py | 2 +- djangorestframework/renderers.py | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/djangorestframework/mixins.py b/djangorestframework/mixins.py index 6ab7ab6e4..1f06dd345 100644 --- a/djangorestframework/mixins.py +++ b/djangorestframework/mixins.py @@ -22,7 +22,7 @@ class CreateModelMixin(object): self.object = serializer.object self.object.save() return Response(serializer.data, status=status.HTTP_201_CREATED) - return Response(serializer.error_data, status=status.HTTP_400_BAD_REQUEST) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class ListModelMixin(object): diff --git a/djangorestframework/renderers.py b/djangorestframework/renderers.py index 4a14d5ee8..a94fcd5c5 100644 --- a/djangorestframework/renderers.py +++ b/djangorestframework/renderers.py @@ -248,11 +248,16 @@ class DocumentingTemplateRenderer(BaseRenderer): # Creating an on the fly form see: http://stackoverflow.com/questions/3915024/dynamically-creating-classes-python fields = {} - for k, v in self.view.get_serializer().fields.items(): + object, data = None, None + if hasattr(self.view, 'object'): + object = self.view.object + serializer = self.view.get_serializer(instance=object) + for k, v in serializer.fields.items(): fields[k] = field_mapping[v.__class__.__name__]() OnTheFlyForm = type("OnTheFlyForm", (forms.Form,), fields) - - form_instance = OnTheFlyForm(self.view.get_serializer().data) + if object: + data = serializer.data + form_instance = OnTheFlyForm(data) return form_instance def _get_generic_content_form(self, view): From 59a0bc55af871a538843d1a6dd2442d374bd8b26 Mon Sep 17 00:00:00 2001 From: Marko Tibold Date: Sat, 8 Sep 2012 22:01:12 +0200 Subject: [PATCH 3/4] Don't fill in the form after a DELETE. --- djangorestframework/renderers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/djangorestframework/renderers.py b/djangorestframework/renderers.py index a94fcd5c5..6d00c4c5c 100644 --- a/djangorestframework/renderers.py +++ b/djangorestframework/renderers.py @@ -255,7 +255,7 @@ class DocumentingTemplateRenderer(BaseRenderer): for k, v in serializer.fields.items(): fields[k] = field_mapping[v.__class__.__name__]() OnTheFlyForm = type("OnTheFlyForm", (forms.Form,), fields) - if object: + if object and not self.view.request.method == 'DELETE': # Don't fill in the form when the object is deleted data = serializer.data form_instance = OnTheFlyForm(data) return form_instance From ef0bf1e775161578ab16be165d4bdb8003040f6c Mon Sep 17 00:00:00 2001 From: Marko Tibold Date: Sat, 8 Sep 2012 22:50:54 +0200 Subject: [PATCH 4/4] Fix failing test. --- djangorestframework/renderers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/djangorestframework/renderers.py b/djangorestframework/renderers.py index 6d00c4c5c..45cdbbbba 100644 --- a/djangorestframework/renderers.py +++ b/djangorestframework/renderers.py @@ -234,7 +234,8 @@ class DocumentingTemplateRenderer(BaseRenderer): In the absence on of the Resource having an associated form then provide a form that can be used to submit arbitrary content. """ - + if not hasattr(self.view, 'get_serializer'): # No serializer, no form. + return # We need to map our Fields to Django's Fields. field_mapping = dict([ [FloatField.__name__, forms.FloatField],