Skip to content

Commit

Permalink
Add docs for add_form_class and edit_form_class, and add form.set_req…
Browse files Browse the repository at this point in the history
…uest() hook.
  • Loading branch information
af committed Nov 27, 2011
1 parent ee02473 commit 920ff04
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
40 changes: 38 additions & 2 deletions README.rst
Expand Up @@ -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::

Expand All @@ -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
-------------

Expand Down
14 changes: 14 additions & 0 deletions djangbone/tests.py
Expand Up @@ -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.
Expand All @@ -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):
"""
Expand Down
4 changes: 4 additions & 0 deletions djangbone/views.py
Expand Up @@ -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.
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 920ff04

Please sign in to comment.