<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>No One Is Perfect &#187; method</title>
	<atom:link href="http://watchitlater.com/blog/tag/method/feed/" rel="self" type="application/rss+xml" />
	<link>http://watchitlater.com/blog</link>
	<description>A reluctant foray into the world of blogging.</description>
	<lastBuildDate>Tue, 08 Nov 2011 12:32:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Django RESTful resources</title>
		<link>http://watchitlater.com/blog/2010/02/django-restful-resources/</link>
		<comments>http://watchitlater.com/blog/2010/02/django-restful-resources/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 13:34:25 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[My Code]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[method]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[resource]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://watchitlater.com/blog/?p=140</guid>
		<description><![CDATA[Last year I blogged about a neat trick in Django to have multiple views per HTTP verb. Since then I&#8217;ve been playing with RESTful applications and decided to see if there was a nicer way to expose &#8220;resources&#8221; in Django. The following is what I&#8217;ve come up with so far. Listing: router.py from django.http import [...]]]></description>
			<content:encoded><![CDATA[<p>Last year I blogged about a neat trick in Django to have <a href="/blog/2009/06/django-and-multiple-methods-per-url-pattern/">multiple views per HTTP verb</a>. Since then I&#8217;ve been playing with RESTful applications and decided to see if there was a nicer way to expose &#8220;resources&#8221; in Django. The following is what I&#8217;ve come up with so far.</p>
<p><strong>Listing: router.py</strong></p>
<pre name="code" class="py:nogutter">
from django.http import Http404, HttpResponseNotAllowed

def get_handler_method(request_handler, http_method):
    try:
        handler_method = getattr(request_handler, http_method.lower())
        if callable(handler_method):
            return handler_method
    except AttributeError:
        pass

class Resource:

    http_methods = [&#x27;GET&#x27;, &#x27;POST&#x27;, &#x27;HEAD&#x27;, &#x27;PUT&#x27;, &#x27;DELETE&#x27;, &#x27;OPTIONS&#x27;, &#x27;TRACE&#x27;]

    @classmethod
    def dispatch(cls, request, *args, **kwargs):
        request_handler = cls()

        if request.method in cls.http_methods:
            handler_method = get_handler_method(request_handler, request.method)
            if handler_method:
                return handler_method(request, *args, **kwargs)

        methods = [method for method in cls.http_methods if get_handler_method(request_handler, method)]
        if len(methods) &gt; 0:
            return HttpResponseNotAllowed(methods)
        else:
            raise Http404
</pre>
<p><strong>Listing: views.py</strong></p>
<pre name="code" class="py:nogutter">
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from router import Resource
from models import Document
from django import forms
import identity

class DocumentForm(forms.Form):
    one = forms.CharField()
    two = forms.CharField()
    date = forms.CharField()

def index(request):
    document_links = []
    for document in Document.objects.all():
        url = reverse(&#x27;document&#x27;, args=[document.id])
        document_links.append({ &#x27;identity&#x27;: document.id, &#x27;url&#x27;: url })

    new_form_url = reverse(&#x27;document&#x27;, args=[identity.NEW])
    model = { &#x27;document_links&#x27;: document_links, &#x27;new_form_url&#x27;: new_form_url }
    return render_to_response(&#x27;index.html&#x27;, model)

def success(request, document_id):
    document = get_object_or_404(Document, pk=document_id)
    form = DocumentForm(document.get_values())
    form.is_valid()

    model = { &#x27;form&#x27;: form.cleaned_data, &#x27;index_url&#x27;: reverse(&#x27;index&#x27;) }
    return render_to_response(&#x27;success.html&#x27;, model)

class DocumentView(Resource):

    def get(self, request, document_id):
        if identity.is_new(document_id):
            form = DocumentForm()
        else:
            document = get_object_or_404(Document, pk=document_id)
            form = DocumentForm(document.get_values())

        model = { &#x27;form&#x27;: form, &#x27;index_url&#x27;: reverse(&#x27;index&#x27;) }
        return render_to_response(&#x27;form.html&#x27;, model)

    def post(self, request, document_id):
        if identity.is_new(document_id):
            document = Document()
        else:
            document = get_object_or_404(Document, pk=document_id)

        document.set_values(request.POST)
        document.save()

        form = DocumentForm(document.get_values())
        if form.is_valid():
            url = reverse(&#x27;success&#x27;, args=[document.id])
        else:
            url = reverse(&#x27;document&#x27;, args=[document.id])

        return HttpResponseRedirect(url)
</pre>
<p><strong>Listing: urls.py</strong></p>
<pre name="code" class="py:nogutter">
from django.conf.urls.defaults import *
from django.conf import settings
import os, views

urlpatterns = patterns(&#x27;&#x27;,
    url(r&#x27;^document/(?P&lt;document_id&gt;[A-Za-z0-9\-]+)/$&#x27;, views.DocumentView.dispatch, name=&#x27;document&#x27;),
    url(r&#x27;^success/(?P&lt;document_id&gt;[A-Za-z0-9\-]+)/$&#x27;, views.success, name=&#x27;success&#x27;),
    url(r&#x27;^$&#x27;, views.index, name=&#x27;index&#x27;),
)

if settings.DEBUG:
    urlpatterns += patterns(&#x27;&#x27;,
        (r&#x27;^static/(?P&lt;path&gt;.*)$&#x27;, &#x27;django.views.static.serve&#x27;,
            {&#x27;document_root&#x27;: os.path.join(os.path.dirname(__file__), &#x27;static&#x27;)}),
    )
</pre>
<p>It does add a little bit more magic to the views (since you don&#8217;t actually see the dispatch method at all) but it benefits from simpler mapping in urls.py, as well as an easier way to figure out what instance method on a Resource subclass gets called for each HTTP verb. Never felt that comfortable with popping-off of kwargs in <a href="/blog/2009/06/django-and-multiple-methods-per-url-pattern/">last year&#8217;s post</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://watchitlater.com/blog/2010/02/django-restful-resources/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Django and multiple methods per url pattern</title>
		<link>http://watchitlater.com/blog/2009/06/django-and-multiple-methods-per-url-pattern/</link>
		<comments>http://watchitlater.com/blog/2009/06/django-and-multiple-methods-per-url-pattern/#comments</comments>
		<pubDate>Sun, 14 Jun 2009 13:17:41 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[method]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://watchitlater.com/blog/?p=39</guid>
		<description><![CDATA[HTTP verbs are not used to determine the route to a view method by deliberate design in Django. Sometimes I find it useful to be able to specify different methods for the same url pattern &#8211; one per HTTP verb. The Django book contains an interesting example of how this can be done using the [...]]]></description>
			<content:encoded><![CDATA[<p>HTTP verbs are not used to determine the route to a view method by deliberate design in Django. Sometimes I find it useful to be able to specify different methods for the same url pattern &#8211; one per HTTP verb. The Django book contains an interesting <a href="http://www.djangobook.com/en/2.0/chapter08/">example</a> of how this can be done using the <em>django.conf.urls.defaults.url</em> method to separate POST from GET processing. I&#8217;ve extended the example to provide handling to cover the standard HTTP verbs.</p>
<p><strong>Listing: router.py</strong></p>
<pre name="code" class="py:nogutter">
from django.http import Http404, HttpResponseNotAllowed
from django.conf.urls.defaults import url

GET = 'GET'
PUT = 'PUT'
POST = 'POST'
HEAD = 'HEAD'
TRACE = 'TRACE'
DELETE = 'DELETE'
OPTIONS = 'OPTIONS'

HTTP_METHODS = (GET, POST, PUT, HEAD, DELETE, OPTIONS, TRACE)

def dispatch(request, *args, **kwargs):
    view = kwargs.pop(request.method, None)
    if view:
        for method in HTTP_METHODS:
            kwargs.pop(method, None)
        return view(request, *args, **kwargs)
    else:
        allowed_methods = []
        for method in HTTP_METHODS:
            if kwargs.pop(method, None):
                allowed_methods.append(method)
        if allowed_methods:
            return HttpResponseNotAllowed(allowed_methods)
        else:
            raise Http404

def mapping(regex, viewname, get = None, post = None, put = None, delete = None, \
            head = None, options = None, trace = None):
    views = { GET: get, POST: post, PUT: put, DELETE: delete, HEAD: head, \
              OPTIONS: options, TRACE: trace }
    return url(regex, dispatch, views, viewname)
</pre>
<p><strong>Listing: urls.py</strong></p>
<pre name="code" class="py:nogutter">
from django.conf.urls.defaults import *
from router import mapping
import views

urlpatterns = patterns('',
    (r'^$', views.index),
    mapping(r'^document/(?P&lt;document_id&gt;[A-Za-z0-9]+)/$', 'single_document',
            views.single_document_get, views.single_document_post),
)
</pre>
<p>Works for me.</p>
<p>UPDATE: There is also a more object-oriented/RESTful way to do this, as outlined in my <a href="/blog/2010/02/django-restful-resources/">Django RESTful resources</a> blog post.</p>
]]></content:encoded>
			<wfw:commentRss>http://watchitlater.com/blog/2009/06/django-and-multiple-methods-per-url-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

