It's not hard. Really.
In url-configs each entry is simply a regular expression which has to match a url that is visited by an end user. r'^main/(?P<slug>[-\w]+)/'
will for example match with: http://localhost:8000/main/some-slug/
You can use a special kind of syntax in your regular expression to extract matched data and pass that data as a variable to your view function.
The bit that does that is (?P<slug>[-\w]+)
it puts matched words (in this case a slug) into a variable called slug (the <slug>
part, it defines the variable name). In this humble example the slug variable will be set to "some-slug".
The variable will be accessible in your view like this:
from django.http import HttpResponse
def handle_my_view(request, slug=homepage):
# do stuff with slug
return HttpResponse("I did stuff with slug: {}".format(slug))
Learn more about, and fiddle with regular expressions
At http://www.regexr.com
But why do i see slugs used in models?:
A slug (or named variable, coming from a url 'interception') can be used for anything. Commonly the slug variable itself will be used to retrieve a database record of some sorts... And that involves using models.
You can do whatever you want with them; add stuff, subtract stuff, capitalize, whatever. The sky is the limit.
From the Django docs:
https://docs.djangoproject.com/en/1.10/topics/http/urls/#named-groups
Named groups
The above example used simple, non-named regular-expression groups (via parenthesis) to capture bits of the URL and pass them as positional arguments to a view. In more advanced usage, it’s possible to use named regular-expression groups to capture URL bits and pass them as keyword arguments to a view.
In Python regular expressions, the syntax for named regular-expression groups is (?Ppattern), where name is the name of the group and pattern is some pattern to match.
Here’s the above example URLconf, rewritten to use named groups:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]
This accomplishes exactly the same thing as the previous example, with one subtle difference: The captured values are passed to view functions as keyword arguments rather than positional arguments. For example:
A request to /articles/2005/03/
would call the function views.month_archive(request, year='2005', month='03')
, instead of views.month_archive(request, '2005', '03')
.
A request to /articles/2003/03/03/
would call the function views.article_detail(request, year='2003', month='03', day='03')
.
In practice, this means your URLconfs are slightly more explicit and less prone to argument-order bugs – and you can reorder the arguments in your views’ function definitions. Of course, these benefits come at the cost of brevity; some developers find the named-group syntax ugly and too verbose.