This app makes urls usage DRYer. It maps URL keywords to a model object instance by passing the object instance as argument to the URL.
In short, having an article
model instance, you can write this:
<a href="{{ url('article:detail', article) }}">View this article</a>
While you have been writing this so far:
<a href="{{ url('article:detail', year=article.year, month=article.month, slug=article.slug) }}">View this article</a>
This is for your templates as well as for your reverse()
and preserves
other urls to work.
Right now it is build for Jinja2 using the easy-to-use Jingo adapter. If you are using plain Django template, refer to version 0.3.1. A new version for plain Django should come out later on.
pip install django-model-urls
or get the bleeding edge version:
pip install git+https://github.com/vinyll/django-model-urls.git
Add model_urls to your settings file:
INSTALLED_APPS = (
'jingo',
'model_urls',
)
And you're done!
In the examples below we will consider this model:
class Article(models.Model):
slug = models.SlugField()
title = models.CharField(max_length=50)
date = models.DateField()
@property
def year(self):
return self.date.year
@property
def month(self):
return self.date.month
and this urls:
urlpatterns = patterns('',
url(r'^article/(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[\w-]+)/$',
ArticleView.as_view(), name="article_details"),
)
and article
being an instance of the Article
class.
url('article_details', article)
from model_urls.urlresolvers import reverse
reverse('article_details', article)
Both will generate a url in this format:
/2014/11/how-to-optimize-django-urls/
Basically you should be able to use url()
and reverse()
in all cases.
However, these tools are also available:
url(viewname, *args, **kwargs)
will try to detect an instance in arguments and choose wheter to use simple_url() or model_url() otherwise.simple_url(viewname, *args, **kwargs)
is an alias to Jingo'surl()
helper to force using it.model_url(viewname, instance, *args, **kwargs)
will generate the url from the instance in first argument.
These functions are available in model_urls.urlresolvers
.
model_reverse(viewname, instance, urlconf=None, args=None, kwargs=None, prefix=None, current_app=None)
will generate the url based on the instance properties.reverse(viewname, *args, **kwargs)
will fallback to model_reverse() if an instance is found in arguments or to Django's reverse() otherwise.
An optional configuration is for your settings is:
MODEL_URLS_HELPER_OVERRIDE = False
This option will not allow the Jingo's url()
helper to be overriden by the
one from model_urls.
In this case you should use model_url()
to use an instance.
A common use case is switching from pk based url to slug. Using django-model-urls means updating the urls.py file to consider slug without altering views or template files.
Refer to tests.py to see more usages.