English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
A view is a web page 'type' in the Django application, providing specific features and having a specific template. For example, in a blog application, there may be the following views:
Blog homepage - Displays the last few articles. Enter the 'detail' page- Permanent link page for a single item. Archive page - Displays all entries for each month of the given year. Monthly archive page - Displays all items for each day of the given month. Archive page - Display all entries for a specific day. Comment operation - Handle a given input for posting comments.
In our poll application, there are the following four views:
The 'index' page of the question- Display the last few questions. The 'detail' page of the question - Display a question text without results but with a form to vote. The 'results' page of the question - Display the results of a specific question. Voting operation - Handle voting for a specific question and make a specific choice.
In Django, web pages and other content are provided by views. Each view is represented by a simple Python function (or method, based on a class view). Django selects a view by examining the most popular URL requested by the public (more precisely, the part of the URL after the domain).
A URL pattern is the general form of a simple URL. - For example:/newsarchive/<year>/<month>/.
Now, let's add some views to the/views.py. These views are slightly different because they need a parameter:
def detail(request, question_id): return HttpResponse("You're looking at question %s." % question_id) def results(request, question_id): response = "You're looking at the results of question %s." return HttpResponse(response % question_id) def vote(request, question_id): return HttpResponse("You're voting on question %s." % question_id)
These new views are added to the polls.urls module as follows, polls/The code in the urls.py file is as follows:
Example from django.conf.urls import url app_name = 'polls' # ex: /polls/ urlpatterns = [ # ex: /polls/5/ $, views.results, name='results'),-9]+)/$, views.index, name='index'), # ex: /polls/5/$, views.detail, name='detail'),/ $, views.results, name='results'),-9]+)/$, views.detail, name='detail'),/results # ex: /polls/5/vote/ $, views.results, name='results'),-9]+)/vote/$, views.vote, name='vote'), ]
You can open/polls/34/". It will run the detail() method and display any provided URL content. Try accessing "/polls/34/$, views.detail, name='detail'),/" and "/polls/34/vote/" – This will display placeholder results and the voting page.
include() can easily include plugins and URLs. Because polls have their own URL configuration (polls/urls.py), which can be placed at/polls/or '/fun_polls/or at/content/polls/An application can still work, regardless of the root path or any other path.
Below is if the user enters “}}/polls/34/”,in this system,what will happen:
Django will find the matching'^polls/') Then,Django will remove the matched text ("polls/"
and send the remaining text – "34/" – to 'polls.urls' URL configuration for further processing matching r'^(?P<question_id>[0-9]+)/$' to call the detail() view,as follows:
detail(request=<HttpRequest object>, question_id='34')
question_id='34' is from (?P<question_id>[0-9]+) part,using the surrounding pattern brackets “capture” the matching text,and pass it as a parameter to the view function; ?P<question_id> defines the name that will be used to identify the matching pattern; and [0-9]+ The regular expression matches a sequence of digits (in a digit).
Since the URL pattern is a regular expression,it can be used to do some things,with no limits.And there is no need to add URL as .html – unless you want,in which case,you can do this:
url(r'^polls/latest\.html$', views.index),
Each view is responsible for one of two things:returning an HttpResponse object containing the content of the requested page,or throwing an exception,such as HTTP 404. Modify polls/The code in the views.py file is as follows:
from django.http import HttpResponse from .models import Question def index(request): latest_question_list = Question.objects.order_by('-pub_date)[:5] output = ', '.join([q.question_text for q in latest_question_list]) return HttpResponse(output) # Leave the rest of the views (detail, results, vote) unchanged
There is a problem here,through:Web design is hard-coded in the view.If you want to change the appearance of the page,you must edit this Python code.Therefore,let us use the Django template system by creating views that can use templates to separate the Python code.polls/templates/polls/index.html Will the following code:
{% if latest_question_list %} <ul> {% for question in latest_question_list %} <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li> {% endfor %} </ul> {% else %} <p>No polls are available.</p> {% endif %}
Now let's update the home page view polls/views.py uses the following template (code):
from django.http import HttpResponse from django.template import loader from .models import Question def index(request): latest_question_list = Question.objects.order_by('-pub_date)[:5] template = loader.get_template('polls/index.html') context = { 'latest_question_list': latest_question_list, } return HttpResponse(template.render(context, request))
This code loads the template and calls polls/index.html, and then pass it to its context. The context is a dictionary mapping Python objects to template variable names. Now access the URL (http://127.0.0.1:8000/polls/View results:
This is a very common usage to load a template, fill the context, and render the result to return an HttpResponse object. Django provides a shortcut. Below is the complete index() view, rewritten as polls/views.py is as follows:
from django.shortcuts import render from .models import Question def index(request): latest_question_list = Question.objects.order_by('-pub_date)[:5] context = {'latest_question_list': latest_question_list} return render(request, 'polls/index.html', context)
Note that once we have done this in all views, we no longer need to import loaders and HttpResponse objects (if you still want to keep HttpResponse, if there are still methods such as detail, results, and vote.
Now, let's solve this detailed view problem - A page displaying the given survey question text. Here you add view code (polls/views.py):
from django.http import Http404 from django.shortcuts import render from .models import Question # ... def detail(request, question_id): try: question = Question.objects.get(pk=question_id) except Question.DoesNotExist: raise Http404("Question does not exist") return render(request, 'polls/detail.html', {'question': question})
Note here: the view raises HTTP404exception if the requested ID does not exist.
we will discuss what can be done with polls/If you want to quickly use the above example, polls/templates/polls/detail.html file only needs to contain:
{{ question }}
trigger 404 Error, now we request a non-existent question, such as: http://127.0.0.1:8000/polls/100/, the display result is as follows:
a very common usage if the object does not exist using get() and raising HTTP404Error. Django provides a shortcut. Here is the detail() view, polls/views.py rewrite:
from django.shortcuts import get_object_or_404, render from .models import Question # ... def detail(request, question_id): question = get_object_or_404(Question, pk=question_id) return render(request, 'polls/detail.html', {'question': question})
get_object_or_404() function takes a Django model as the first parameter and an arbitrary number of keyword arguments, which are passed to the model's get() function.
if the object does not exist it will cause HTTP404.
there is also get_list_or_404() function works like get_object_or_404()- besides using filter() instead of get() method. If the list is empty it will cause HTTP404.
Back to our polls application detail() view. Due to context variable issues, here the polls/detail.html template looks like this:
<h1{{ question.question_text }}</h1> <ul> {% for choice in question.choice_set.all %} <li>{{ choice.choice_text }}</li>/li> {% endfor %} </ul>
The template system uses dot query syntax to access variable properties. In this instance {{question.question_text }}, the first Django indeed looks up in the question object dictionary. If it can't find it, it tries an attribute query – if the attribute query fails, it tries a list index lookup.
Now test the code we wrote above, open it in the browser: http://127.0.0.1:8000/polls/5/ The result is as follows:
Remember, when we are in 'polls'/index.html links to a question, the part that is hard-coded is like this:
<li><a href="/polls/{{question.id}}/">{{question.question_text}}</a></li>
The problem with this hard-coded, tightly coupled method is that it uses a lot of templates when changing the project's URL. However, since the 'url()' function with the defined name parameter is in the 'polls.urls' module, you can remove the dependency on the specific URL path defined in the URL configuration by using the {% url %} template tag:
<li><a href="{etail'question.id%}">{{question.question_text}}</a></li>
This method works by defining the URL to be searched for in the 'polls.urls' module. You can see the URL name definition for 'detail' as follows:
... # the 'name' value as called by the {% url %} template tag $, views.results, name='results'),-9]+)/$, views.index, name='index'), ...
If you want to change the URL of the voting detail view to another, maybe like 'polls'/specifics/12/ To replace in the template (or templates), you need to 'polls'/urls.py change it:
... # added the word 'specifics' url(r'^specifics/(?P<question_id>[0-9]+)/$, views.index, name='index'), ...
This tutorial project has only one application - In a real Django project, there may be five, ten, twenty, or even more applications. How does Django distinguish their URL names? For example, the voting application has a detail view, so there may be the same application in a blog project. How can you use the {% url %} template tag to let Django know which application has such a view when creating a URL?
The answer is to add the namespace to the URLconf. In 'polls'/The 'urls.py' file, continue forward, add the application name and set the application namespace, open 'polls'/urls.py:
Example from django.conf.urls import url from . import views app_name = 'polls' urlpatterns = [ $, views.results, name='results'),-9]+)/$, views.index, name='index'), $, views.results, name='results'),-9]+)/$, views.detail, name='detail'),/results $, views.results, name='results'),-9]+)/vote/$, views.vote, name='vote'), ]
Now modify polls/Open the index.html template, polls/templates/polls/Add the following code to the index.html file:
<li><a href="{etail'question.id%}">{{question.question_text}}</a></li>
Make it point to the 'detail' view in the namespace, open polls/templates/polls/The index.html file is as follows:
<li><a href="{olls:detail'question.id%}">{{question.question_text}}</a></li>