django-restful-model-views


A Django contribution to help create RESTful Web applications.

Update

As I explained in this blog post, I am suspending work on this project to support the work of Andreas Stuhlmueller who is going to be implementing a more comprehensive RESTful API for Django as part of the Google Summer of Code. As his work looks like the most promising implementation, and many of his ideas are compatible with mine, I would prefer to spend my time supporting him by providing feedback, testing releases, possibly contributing documentation, etc. rather than developing partially overlapping code.

If you are interested, here are some relevant links to Andreas' proposal:

Background

As someone who has been away from Python for a little while and is new to Django and to the REST philosophy, I only set out to better familiarize myself with Django and to better understand REST, not to create this contribution. However, this is where my exploration of Django and REST have taken me. The following blog posts chronicle this exploration and should provide insight into the approach taken here:

At this stage, I offer this contribution only as an attempted proof of concept, and leave it for more experienced Django developers to judge if this approach is sound. I have attempted to follow best practices for implementing pure REST--as much as pure REST can be implemented--and to do so in a way that is compatible with Django. However, at this point, the implemenation is incomplete, and hasn't been tested in a real application environment.

Installation and Setup

Step 1: Checkout from Subversion: svn checkout http://django-restful-model-views.googlecode.com/svn/trunk/ restful_model_views

Step 2: Copy or link this directory under django/contrib .

Step 3: In settings.py, separate the applications that should be RESTful: ``` RESTFUL_APPS = ( 'mysite.myrestfulapp', )

INSTALLED_APPS = RESTFUL_APPS + ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', ) ```

Step 4: In urls.py, add RESTful URL patterns: from django.contrib.restful_model_views.restful_urls import get_restful_patterns urlpatterns += get_restful_patterns()

Step 5: Instead of a single views.py, create a directory called 'views' in your RESTful application, and don't forget to add an empty __init__.py file under it, so Python knows it's a module. Now, for each model class that should have RESTful views, create a new module and class under views based on the name of the model. A minimal implementation for a model class called 'Items' would contain this code in views/Items.py: ``` from mysite.myrestfulapp.models import Items from django.contrib.restful_model_views.ModelResources import ModelResources, edit, create, dispatch

class Items(ModelResources): pass

class Items_Member (ModelResources.ModelResources_Member): pass

```

This minimal implementation makes the underlying view methods in Resources available to Django for the model. You can refer to the django.contrib.restful_model_views.Resources module to see a full implemenation, otherwise, the basic structure of a RESTful model view looks like this: ``` class Resources def GET(request): pass

def POST(request):
  pass

class Creator:

  def GET(self, request):
    pass

class Resources_Member:

  def GET(self, request):
    pass

  def PUT(self, request):
    pass

  def DELETE(self, request):
    pass

  class Editor:

    def GET(self, request):
      pass

```

[TODO: map these methods to form actions] Override any methods you need to customize. Otherwise, the default implemenations are designed to use generic views, so the appropriate templates need to be in the usual places. (Consult the Django generic views documentation if you don't know where these are.) Also note that to overload POST for PUT and DELETE operations, you will have to add a form element called '_method' with the appropriate values 'PUT' or 'DELETE'.

Development Roadmap

This contribution is currently in a 'proof of concept' stage, although there are unit tests distributed with it, so what is there should at least work. Immediate/obvious work to do includes: * Implement appropriate default generic views for all methods in Resources and Resources_Member classes. * Allow this approach to work with a standard views.py module, to accomodate the case in which perhaps only a few RESTful methods will be overridden. * Simplify deployment so that even minimal view classes like the Items.py module mentioned above won't be necessary if only the default functionality of the Resources module is needed. (Maybe this can be done by dynamically adding the Resources module to views at runtime?) I may also try to find a way to add the RESTful urlpatterns automatically without having to add code to urls.py. The answer may be to make this a full-fledged middleware component within Django, but currently, I am not sure that is the correct route to take. The following are discussed in more detail in Evolving a RESTful Django Contribution: * ~~Refactor to decouple resource view class structure (with default raise Http404 implementations) from ORM/generic view code. This will allow for more flexible definition of resources when they don't directly map to models.~~ * Along with the above refactoring, add more specifications options, such as specifying a list of resource names or a dictionary of resource names mapped optionally to model classes. Consider looking for this in urls.py as well as keeping the current RESTFUL_APPS approach in settings.py. * ~~Implement direct dispatching to PUT and DELETE methods instead of just relying on overloading post.~~ * Implement something like respond_to in Rails. * Implement something similar to link_to, form_tag and form_for in Rails. * ~~Change '_action' to '_method'.~~ * Add service discovery views/templates. Look into ATOM Publishing Protocol, WADL, etc.

Background Resources

The following are some of the resources that have shaped my thinking and approach to this contribution: * Resource-oriented vs. activity-oriented Web services * REST Controller for RAILS on Charlie Savage’s Blog * (Another) Rest Controller for Rails by Peter Williams * RESTful Rails Development by Ralf Wirdemann and Thomas Baustert. * RESTful and User-Friendly URLS by Bill Venners * RESTed and Confused on Don Park’s Daily Habit

[TODO: add introductory REST links, relevant Django links?]

Acknowledgements

Thank you to those who have taken the time to give valuable feedback so far: * Malcolm Tredinnick * David Larlet from biologeek.com * Samus (sorry, I don't have more information)

Alternate approaches: * Improving Django: Generic views for RESTful web services * Django Collection contribution * Django CRUD API

Contact

adam smith

Project Information

Labels:
Django REST Python