Fork me on GitHub

Resources

The resource is the most basic concept in writing RESTful applications. A resource is identified by a URI, and clients interact with resources using the standard HTTP methods. Detailed information on the URI schema and the behavior of resources over HTTP is provided in the URI documentation.

Defining Resources

Resources are subclasses of dagny.Resource. Actions are methods on these subclasses, decorated with @action. Here’s a short example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from dagny import Resource, action
from django.shortcuts import get_object_or_404, redirect

from django.contrib.auth import forms, models

class User(Resource):

    @action
    def index(self):
        self.users = models.User.objects.all()

    @action
    def new(self):
        self.form = forms.UserCreationForm()

    @action
    def create(self):
        self.form = forms.UserCreationForm(request.POST)
        if self.form.is_valid():
            self.user = self.form.save()
            return redirect(self.user)

        response = self.new.render()
        response.status_code = 403 # Forbidden
        return response

    @action
    def show(self, username):
        self.user = get_object_or_404(models.User, username=username)

    @action
    def edit(self, username):
        self.user = get_object_or_404(models.User, username=username)
        self.form = forms.UserChangeForm(instance=self.user)

    @action
    def update(self, username):
        self.user = get_object_or_404(models.User, username=username)
        self.form = forms.UserChangeForm(self.request.POST, instance=self.user)
        if self.form.is_valid():
            self.form.save()
            return redirect(self.user)

        response = self.edit.render()
        response.status_code = 403
        return response

    @action
    def destroy(self, username):
        self.user = get_object_or_404(models.User, username=username)
        self.user.delete()
        return redirect('/users')

Resource uses django-clsview to define class-based views; the extensive use of self is safe because a new instance is created for each request.

You might notice that there are no explicit calls to render_to_response(); most of the time you’ll want to render the same templates: "user/index.html", "user/new.html", "user/show.html" and "user/edit.html". Therefore, if your action doesn’t return anything (i.e. returns None), a template corresponding to the resource and action will be rendered. See the renderer documentation for more information.

Decorating Resources

If you want to apply a view decorator to an entire Resource, you can use the _decorate() method (as provided by django-clsview):

class User(Resource):
    ...
User = User._decorate(auth_required)

Note that this returns a new resource, so you need to re-assign the result to the old name.

Decorating Actions

Because actions don’t have the typical function signature of a Django view (i.e. view(request, *args, **kwargs)), most view decorators won’t work on an action method. For this reason, Dagny provides a simple decorator-wrapper which will adapt a normal view decorator to work on an action method. Use it like this:

class User(Resource):
    @action
    @action.deco(auth_required)
    def edit(self, username):
        ...

deco() is a staticmethod on the Action class, purely for convenience. Remember: @action.deco() must come below @action, otherwise you’re likely to get a cryptic error message at runtime.