<commit_before>=========
Djangbone
=========

Djangbone is a small django app that makes it easy to work with `Backbone.js
<http://backbonejs.org/>`_ frontends. More specifically, it allows you to
quickly build a backend that works with the default Backbone.sync implementation.

Djangbone provides one abstract class-based view (BackboneView), which gives you
hooks to customize it easily.


Example Usage
-------------

After downloading/installing djangbone, all you need to do is subclass
`BackboneView`, and then wire it up in your urlconf.

In myapp/views.py::

    from myapp.models import Widget
    from djangbone.views import BackboneView

    class WidgetView(BackboneView):
        base_queryset = Widget.objects.all()
        serialize_fields = ('id', 'name', 'description', 'created_at')

In myapp/urls.py::

    from myapp.views import WidgetView

    # Create url patterns for both "collections" and single items:
    urlpatterns = patterns('',
        url(r'^widgets', WidgetView.as_view()),
        url(r'^widgets/(?P<id>\d+)', WidgetView.as_view()),
    )

If you want to run the djangbone tests, you'll need to add `"djangobone"` to your
INSTALLED_APPS, and run `python manage.py test djangbone`. The tests use
`django.contrib.auth`, so that app will also need to be in your INSTALLED_APPS
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
-------------

There's a decent chance that you'll want to wrap your BackboneView subclass
with additional functionality, for example to only allow registered users to
access this view. You can use django's method_decorator on BackboneView's
dispatch() method to do this as follows::

    from django.contrib.auth.decorators import login_required
    from django.utils.decorators import method_decorator

    class WidgetView(BackboneView):
        ...

        @method_decorator(login_required)
        def dispatch(self, request, *args, **kwargs):
            return super(WidgetView, self).dispatch(*args, **kwargs)


You might also want to vary the base_queryset depending on the request (or an
extra url parameter). You can also override dispatch() to do this, for example::

    class WidgetView(BackboneView):
        base_queryset = None

        def dispatch(self, request, *args, **kwargs):
            self.base_queryset = Widgets.objects.filter(owner=request.user)
            return super(WidgetView, self).dispatch(*args, **kwargs)

Assumptions
-----------

Djangbone makes a few assumptions about your models in order to work:

    * your model has an integer primary key named 'id'


Alternatives
------------

Djangbone is designed to be a simple way to serialize your models to JSON in
a way that works with Backbone. It's not trying to be a generalized, 
format-agnostic API generator. If that's what you're looking for, you probably
will want to go with something like tastypie or django-piston instead.

If you're already using django-tastypie, or are looking for a more full-featured API
backend than Djangbone provides, you may want to look at `backbone-tastypie 
<https://github.com/PaulUithol/backbone-tastypie>`_, which overrides
Backbone.sync (via javascript) in a way that works nicely with tastypie.
<commit_msg>Misc changes to the readme.<commit_after>=========
Djangbone
=========

Djangbone is a small django app that makes it easy to work with `Backbone.js
<http://backbonejs.org/>`_ frontends. More specifically, it allows you to
quickly build a backend that works with the default Backbone.sync implementation.

Djangbone provides one abstract class-based view (BackboneView), which gives you
hooks to customize it easily.


Example Usage
-------------

After downloading/installing djangbone, all you need to do is:

#. Subclass ``BackboneView``, and set the ``base_queryset`` and
   ``serialize_fields`` attributes.
#. Wire up the view subclass in your urlconf.

In myapp/views.py::

    from myapp.models import Widget
    from djangbone.views import BackboneView

    class WidgetView(BackboneView):
        # base_queryset is a queryset that contains all the objects that are
        # accessible by the API:
        base_queryset = Widget.objects.all()

        # serialize_fields is a list of model fields that you want to be sent
        # in your JSON resonses:
        serialize_fields = ('id', 'name', 'description', 'created_at')

In myapp/urls.py::

    from myapp.views import WidgetView

    # Create url patterns for both "collections" and single items:
    urlpatterns = patterns('',
        url(r'^widgets', WidgetView.as_view()),
        url(r'^widgets/(?P<id>\d+)', WidgetView.as_view()),
    )

If you want to run the djangbone tests, you'll need to add ``"djangobone"`` to your
INSTALLED_APPS, and run ``python manage.py test djangbone``. The tests use
``django.contrib.auth``, so that app will also need to be in your INSTALLED_APPS
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
-------------

There's a decent chance that you'll want to wrap your BackboneView subclass
with additional functionality, for example to only allow registered users to
access this view. You can use django's method_decorator on BackboneView's
dispatch() method to do this as follows::

    from django.contrib.auth.decorators import login_required
    from django.utils.decorators import method_decorator

    class WidgetView(BackboneView):
        ...

        @method_decorator(login_required)
        def dispatch(self, request, *args, **kwargs):
            return super(WidgetView, self).dispatch(*args, **kwargs)


You might also want to vary the base_queryset depending on the request (or an
extra url parameter). You can also override dispatch() to do this, for example::

    class WidgetView(BackboneView):
        base_queryset = Widgets.objects.all()

        def dispatch(self, request, *args, **kwargs):
            if request.method in ['PUT', 'DELETE']:
                self.base_queryset = Widgets.objects.filter(owner=request.user)
            return super(WidgetView, self).dispatch(*args, **kwargs)

Assumptions
-----------

Djangbone makes a few assumptions about your models in order to work:

    * your model has an integer primary key named 'id'


Alternatives
------------

Djangbone is designed to be a simple way to serialize your models to JSON in
a way that works with Backbone. It's not trying to be a generalized, 
format-agnostic API generator. If that's what you're looking for, you probably
will want to go with something like django-tastypie or django-piston instead.

If you're already using django-tastypie, or are looking for a more full-featured API
backend than Djangbone provides, you may want to look at `backbone-tastypie 
<https://github.com/PaulUithol/backbone-tastypie>`_, which overrides
Backbone.sync (via javascript) in a way that works nicely with tastypie.

{'fraction_non_alphanumeric': 0.09080601937744795, 'fraction_numerical': 0.0, 'mean_word_length': 3.4509174311926607, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4752942', 'n_tokens_mistral': 2686, 'n_tokens_neox': 2596, 'n_words': 1132}