8. URLs und Views¶
Nun kannst du beginnen, das Frontend für die marcador App zu bauen. In diesem Abschnitt werden zwei URLs und die dazu gehörigen Views angelegt. Die Erste ist eine einfache Listenansicht aller öffentlichen Lesezeichen, die Zweite eine Liste aller Lesezeichen einer bestimmten Person.
8.1. URLs konfigurieren¶
“A clean, elegant URL scheme is an important detail in a high-quality Web application. Django lets you design URLs however you want, with no framework limitations.”
So that the views can be used, paths must be associated with them. In Django, this is done explicitly with a URL configration (URLconf). We’ll create a new URLconf just for the marcador app, so that later on the project will have a cleaner structure.
8.1.1. Add URLs to the application¶
Create a new file named urls.py
in the directory
mysite/marcador
and paste in the following lines:
1 2 3 4 5 6 7 8 | from django.conf.urls import url
urlpatterns = [
url(r'^user/(?P<username>[-\w]+)/$', 'marcador.views.bookmark_user',
name='marcador_bookmark_user'),
url(r'^$', 'marcador.views.bookmark_list', name='marcador_bookmark_list'),
]
|
Every URLconf must define a variable urlpatterns
which is a list of URLs.
Each URL will be created with the url()
function. In our example url()
is given three parameters: the path, the names of the views, and an identifier
(name), with which you can refer to this URL later. In the documentation you’ll
find a list of further parameters.
With Django the paths are defined as Regular Expressions (regexes). Regexes are a powerful tool with which to describe strings of characters by means of syntactic rules. You can find a detailed introduction to this theme at regular-expressions.info. The Online regex tester and debugger can help you to craft regular expressions for new URLs.
Die RegEx für die Listenansicht r'^$'
besteht aus den Steuerzeichen ^
(Anfang der Zeichenkette) und $
(Ende der Zeichenkette). Da nichts zwischen diesen Zeichen steht, beschreibt sie einen leeren String. Das führt dazu, das die View über den Pfad /
erreichbar ist - sozusagen die Startseite.
Die RegEx für die View mit den Lesezeichen eines bestimmten Benutzers ist etwas komplexer: r'^user/(?P<username>[-\w]+)/$'
. Sie enthält einen variablen Anteil, der es ermöglicht, den Benutzernamen herauszufiltern. So können dann bei /user/alice/
die Lesezeichen von Alice angezeigt werden und bei /user/bob/
die von Bob.
Die RegEx setzt sich wie folgt zusammen: Nach dem Steuerzeichen für den Anfang ^
kommt user/
, ein statischer Teil der genau übereinstimmen muss. Anschließend folgt eine Gruppierung (?P<username>[-\w]+)
. Sie bewirkt, dass alle nachfolgenden Buchstaben, Zahlen, Unterstriche und Bindestriche (definiert durch [-\w]+
) der Variable username
zugeordnet werden. Django übergibt später alle diese Gruppierungen der View als Argumente. Am Ende stehen der statische Teil /
und das Steuerzeichen für das Ende der Zeichenkette $
. Bei Django ist es üblich, alle Pfade mit einem /
enden zu lassen.
8.1.2. Add URLs to the project¶
So that the URLconf for our app can be found, it must be referenced in the root
URLconf. So paste the emphasized line into the file
mysite/mysite/urls.py
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | """mysite URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.8/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Add an import: from blog import urls as blog_urls
2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls))
"""
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^', include('marcador.urls')),
]
|
8.1.3. Test the new URLs¶
Du kannst nun die beiden URLs im Browser aufrufen:
Bei beiden URLs wird eine ViewDoesNotExist
Exception angezeigt. Das bedeutet, dass die URLs richtig aufgelöst werden, jedoch die zugeordnete View nicht existiert.
8.2. Views hinzufügen¶
“A view function, or view for short, is simply a Python function that takes a Web request and returns a Web response.”
Der nächste Schritt ist das Anlegen der Views. Bei Django ist eine View eine Funktion, die ein Request-Objekt entgegennimmt und ein Response-Objekt zurück gibt. Dazwischen steht die Logik, die den Inhalt des Response bestimmt.
8.2.1. A view to display all bookmarks¶
Die erste View gibt eine Liste aller öffentlichen Lesezeichen aus. Öffne dazu die Datei views.py
im Verzeichnis mysite/marcador/
und füge folgenden Code ein:
1 2 3 4 5 6 7 8 9 | from django.shortcuts import get_object_or_404, redirect, render
from .models import Bookmark
def bookmark_list(request):
bookmarks = Bookmark.public.all()
context = {'bookmarks': bookmarks}
return render(request, 'marcador/bookmark_list.html', context)
|
First of all the database query for all public bookmarks is be generated
by means of the ORM, and assigned to the variable bookmarks
. This is
then in turn stored in the dictionary context
. All keys in this
dictionary will later be available to the templates as variables.
Finally the function render()
generates the response object from the
request, the path to the template and the dictionary. render()
is a
shortcut, that carries out several steps in one. You’ll need the
shortcuts get_object_or_404()
and redirect()
for the following
views. You can find out what exactly the shortcuts do in the
documentation.
8.2.2. A view for each user¶
Die zweite View listet alle öffentlichen Lesezeichen eines bestimmten Benutzers auf. Die Zeilen, die du hinzufügen bzw. ändern musst, sind farbig markiert:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404, redirect, render
from .models import Bookmark
def bookmark_list(request):
bookmarks = Bookmark.public.all()
context = {'bookmarks': bookmarks}
return render(request, 'marcador/bookmark_list.html', context)
def bookmark_user(request, username):
user = get_object_or_404(User, username=username)
if request.user == user:
bookmarks = user.bookmarks.all()
else:
bookmarks = Bookmark.public.filter(owner__username=username)
context = {'bookmarks': bookmarks, 'owner': user}
return render(request, 'marcador/bookmark_user.html', context)
|
It has an additional argument username
, with which the requested user in
the database is sought. This contains the same variable as in the regex
of the URLconf. If the user is not found, the HTTP status code
404 will be returned automatically. Whether the user exists and whether he or
she is the logged-in user is checked with the help of the relationship, defined by the field Bookmark.owner
with the model
User
, and the bookmarks loaded. If the view for another user is invoked,
the public bookmarks are filtered with the help of the argument username
.
Bookmarks and user are then added to the context dictionary, so that they can
be accessed in the template later.
8.2.3. Test the new views¶
Beide URLs kannst du jetzt testen:
Of course both currently produce a TemplateDoesNotExist
exception, because
the templates do not yet exist. Notice that the second URL will only work if
you have an user named “admin”. Otherwise use the username of the superuser you
created when you ran the createsuperuser command.