From 920ff04f6d7b2ae666013c68de22fe8c2b5cd0f9 Mon Sep 17 00:00:00 2001 From: Aaron Franks Date: Sun, 27 Nov 2011 10:32:40 -0800 Subject: [PATCH] Add docs for add_form_class and edit_form_class, and add form.set_request() hook. --- README.rst | 40 ++++++++++++++++++++++++++++++++++++++-- djangbone/tests.py | 14 ++++++++++++++ djangbone/views.py | 4 ++++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 5b56f30..46b082b 100644 --- a/README.rst +++ b/README.rst @@ -24,8 +24,6 @@ In myapp/views.py:: class WidgetView(BackboneView): base_queryset = Widget.objects.all() serialize_fields = ('id', 'name', 'description', 'created_at') - add_form_class = ... # Specify this if you want to support POST requests - edit_form_class = ... # Specify this if you want to support PUT requests In myapp/urls.py:: @@ -43,6 +41,44 @@ INSTALLED_APPS, and run `python manage.py test djangbone`. The tests use for the tests to work. +Handling POST and PUT requests +------------------------------ + +Backbone.sync uses POST requests when new objects are created, and PUT requests +when objects are changed. If you want to support these HTTP methods, you need to +specify which form classes to use for validation for each request type. + +To do this, give BackboneView should have ``add_form_class`` (POST) and +``edit_form_class`` (PUT) attributes. Usually you'll want to use a ModelForm +for both, but regardless, each form's save() method should return the model +instance that was created or modified. + +Here's an example (assume AddWidgetForm and EditWidgetForm are both ModelForms):: + + from djangbone.views import BackboneView + from myapp.models import Widget + from myapp.forms import AddWidgetForm, EditWidgetForm + + class WidgetView(BackboneView): + base_queryset = ... + serialize_fields = ... + add_form_class = AddWidgetForm # Used for POST requests + edit_form_class = EditWidgetForm # Used for PUT requests + +If you need access to the ``request`` object in your form classes (maybe to +save ``request.user`` to your model, or perform extra validation), add +a ``set_request()`` method to your form classes as follows:: + + class AddWidgetForm(ModelForm): + class Meta: + model = Widget + + def set_request(self, request): + self.request = request + + # Now you have access to self.request in clean() and save() + + Customization ------------- diff --git a/djangbone/tests.py b/djangbone/tests.py index 8705183..69a6b40 100644 --- a/djangbone/tests.py +++ b/djangbone/tests.py @@ -16,6 +16,13 @@ class Meta: model = User fields = ('username', 'first_name', 'last_name') + def set_request(self, request): + """ + add_form_class and edit_form_class classes can optionally provide this + method in order to get access to the request object. + """ + self.request = request + class EditUserForm(forms.ModelForm): """ Simple ModelForm for testing PUT requests. @@ -24,6 +31,13 @@ class Meta: model = User fields = ('username', 'first_name', 'last_name') + def set_request(self, request): + """ + add_form_class and edit_form_class classes can optionally provide this + method in order to get access to the request object. + """ + self.request = request + class ReadOnlyView(BackboneView): """ diff --git a/djangbone/views.py b/djangbone/views.py index 0b822ac..9fa81e0 100644 --- a/djangbone/views.py +++ b/djangbone/views.py @@ -87,6 +87,8 @@ def post(self, request, *args, **kwargs): except ValueError: return HttpResponse('Invalid POST JSON', status=400) form = self.add_form_class(request_dict) + if hasattr(form, 'set_request'): + form.set_request(request) if form.is_valid(): new_object = form.save() # Serialize the new object to json using our built-in methods. @@ -115,6 +117,8 @@ def put(self, request, *args, **kwargs): except ObjectDoesNotExist: raise Http404 form = self.edit_form_class(request_dict, instance=instance) + if hasattr(form, 'set_request'): + form.set_request(request) if form.is_valid(): item = form.save() wrapper_qs = self.base_queryset.filter(id=item.id)