Per the documentation, patterns is:
A function that takes a prefix, and an arbitrary number of URL
patterns, and returns a list of URL patterns in the format Django
needs.
The first argument to patterns() is a string prefix.
It also provides an example of why you might want to use it:
from django.conf.urls import patterns, url
urlpatterns = patterns('',
url(r'^articles/([0-9]{4})/$', 'news.views.year_archive'),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', 'news.views.month_archive'),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', 'news.views.article_detail'),
)
In this example, each view has a common prefix – 'news.views'.
Instead of typing that out for each entry in urlpatterns, you can
use the first argument to the patterns() function to specify a
prefix to apply to each view function.
With this in mind, the above example can be written more concisely as:
from django.conf.urls import patterns, url
urlpatterns = patterns('news.views',
url(r'^articles/([0-9]{4})/$', 'year_archive'),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', 'month_archive'),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', 'article_detail'),
)
However, note that this function is deprecated:
Deprecated since version 1.8:
urlpatterns should be a plain list of django.conf.urls.url() instances instead.
Note that the explanation as to why includes (with good reason, clearly!):
Thus patterns() serves little purpose and is a burden when teaching
new users (answering the newbie’s question "why do I need this empty
string as the first argument to patterns()?").