Overview

Overview
========

OURL stands for Object URLs.

This small library provides a syntax for Django regexp url system that helps to
overcome a massive use of ``get_object_or_404()`` in views. I.e. here is an url
and a view in application ``myapp``::

    url(r'^artist/([A-Za-z0-9_]+)/', artist_detail)

    def artist_detail(request, artist_slug):
        artist = get_object_or_404(Artist, slug=artist_slug)
        return render_something(artist)
    
Using a syntax from ourl it looks like this::

    ourl(r'^artist/{myapp.Artist.slug}/', artist_detail)

    def artist_detail(request, artist):
        return render_something(artist)

Of course, you can use named regexp groupes syntax::

    url(r'^artist/(?P<artist_slug>[A-Za-z0-9_]+)/', artist_detail)

    ourl(r'^artist/{myapp.Artist.slug:(?P<artist>[A-Za-z0-9_]+)}/', artist_detail)

But do not mix these techniques.

More features
=============

Ourl can handle urls with ``include()`` syntax::

    ourl(r'^{myapp.Artist.slug:(?P<artist>[A-Z]+)}/', include('myapp.urls_artist'))
    # in urls_artist.py:
    ourl(r'^{myapp.Tag.slug:(?P<tag>[A-Z]+)}/$', artist_tag_detail)

Which allows to transform view from first form to second::

    def artist_tag_detail(request, artist_slug, tag_slug):
        artist = get_object_or_404(Artist, slug=artist_slug)
        tag = get_object_or_404(Tag, slug=tag_slug)
        total_tags = TagActions.objects.filter(artist=artist, tag=tag)

    def artist_tag_detail(request, artist, tag):
        total_tags = TagActions.objects.filter(artist=artist, tag=tag)

But, for now, ourl doesn't have syntax for taking objects that depends on parent
object and part of the url (because we haven't invented it yet). For example,
this code can't be truly shortened in ourl::

    url(r'^(?P<artist_slug>[A-Z]+)/(?P<album_slug>[A-Z]+)/', album_detail)

    def album_detail(request, artist_slug, album_slug):
        artist = get_object_or_404(Artist, slug=artist_slug)
        album = get_object_or_404(Album, slug=album_slug, artist=artist)

    # only to this form
    ourl(r'^{myapp.Artist.slug:(?P<artist>[A-Z]+)}/(?P<album_slug>[A-Z]+)/', album_detail)

    def album_detail(request, artist, album_slug):
        album = get_object_or_404(Album, slug=album_slug, artist=artist)

Suggestions are welcome.