Django 1.10 Chinese Document-First Application Part3-view and template, djangopart3-
This tutorial is based on the Django 1.10 Chinese document-the first application Part2-model and management site. We will continue to develop the web page voting application, mainly about how to create an open interface for users.
Overview
A view is a "class" webpage in a Django application. It usually uses a specific function to provide services and has a specific template. For example, a blog application may have the following views:
Blog homepage -- displays the latest published blog;
Blog "details" Page-the link page of each blog;
Year-based archiving page: displays the blogs published in all months in a specific year;
Month-based archiving page: displays the blogs published every day in a specific month;
Date-based archiving page: displays all blogs posted on a specific date;
Comment: Process comments posted on a blog.
In our voting application, we will create the following four views:
Question homepage -- displays the latest Question releases;
Question "details" page -- displays the specific content of a single Question and provides a voting form, but does not display the current voting result of this topic;
Question "result" page -- displays the voting result of a specific Question;
Voting function -- process the vote for Choice in Question.
In Django, webpage pages and other content are transmitted by views. py (views respond to WEB requests ). Each view is represented by a Python function (or a class-based view method. Django selects the corresponding view by comparing the request URL.
On your usual webpage, you may often encounter something similar to "ME2/Sites/dirmod. asp? Sid = & type = gen & mod = Core + Pages & gid = A6CD4967199A42D9B65B1B "url. Fortunately, Django supports more advanced URL patterns (patterns) without the need to write the above complex URLs.
The URL mode is a general URL mode-for example:/newsarchive/<year>/<month>/
.
Django uses the 'urlconfs' configuration to match view functions for URLs. URLconf uses a regular expression to match the URL to the view.
This tutorial provides basic usage of URLconfs. For more information, see django. url.
Edit View
Next, let's open the polls/views. py file and add the following code:
# polls/views.pydef 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)
Then, add the following url mode to the polls/urls. py file and map it to the newly added view.
# polls/urls.pyfrom django.conf.urls import urlfrom . import viewsurlpatterns = [ # ex: /polls/ url(r'^$', views.index, name='index'), # ex: /polls/5/ url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'), # ex: /polls/5/results/ url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'), # ex: /polls/5/vote/ url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),]
Now access "/polls/34/" in the browser. It will run the detail () method and display the ID you provided in the url on the page. Access "/polls/34/results/" and "/polls/34/vote/" to display the predefined pseudo results and voting pages respectively.
The preceding routing process is as follows: when someone accesses the "/polls/34/" Address, Django will first load the mysite. urls module, because it is the ROOT_URLCONF configuration file set in the settings file. Find the urlpatterns variable in the module and perform regular matching on each item in order. When it matches ^ polls/, it will strip out the matched text polls/in the url, and then pass the remaining text "34/" to "polls. urls. In polls. urlsr’^(?P<question_id>[0-9]+)/$’
The final result is to call the detail () view corresponding to this mode and pass 34 as the parameter:
detail(request=<HttpRequest object>, question_id='34')
Question_id = '34 'is from(?P <question_id> [0-9])
. Use the parentheses around the pattern to "capture" the text that matches the pattern and send it as a parameter to the view function;?P<question_id>
Define a pattern for identification matching;[0-9]+
Is a regular expression that matches a string of numbers.
Because the URL pattern is a regular expression, there is no limit on how you use them. Not a complicated URL like .html -- unless you insist on doing so, you can do this in this case:
url(r'^polls/latest\.html$', views.index),
However, do not do this. This is silly.
Compile a view with actual functions
Each view function is only responsible for one of two tasks: returning an HttpResponse object containing the requested page content, or throwing an exception such as Http404. How to do these two things depends on your own ideas.
Your view can read or not read records from the database. It can use a template system, such as Django's or third-party Python template system or not. You can generate PDF files, output XML files, and create ZIP files instantly. You can use any Python library you want. Django only needs to return an HttpResponse. Or throw an exception.
For convenience, let's use the Django database API described in Part1. The following is a new index () view, which displays the latest five questions records in the system and is separated by commas:
# Polls/views. pyfrom django. http import HttpResponsefrom. models import Questiondef 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) # Keep other views (detail, results, vote) Unchanged
Here is a problem: the page design is hardcoded in the view. If you want to change the appearance of the page, edit the Python code. Therefore, we use the Django template system to separate the page design from Python by creating a template that can be called by the view.
First, create a directory named templates under your polls directory. Django will search for the template here.
The templates configuration in settings. py of the Project determines how Django loads the rendering template. Set APP_DIRS to True. DjangoTemplates searches for the "templates" subdirectory under the directory of each application contained in INSTALLED_APPS.
In the newly created templatesdirectory, create another directory named "polls" and create a file named "index.html" in it. In other words, your template should be polls/templates/polls/index.html. Because the app_directories template loader works as described above, you can simply reference this template in Django as polls/index.html (saving the previous path ).
Template namespace: if we put the template directly in polls/templates (instead of creating another polls subdirectory), it is actually a bad idea. Django will select the first template that matches the name it finds. If you have a template with the same name in different applications, Django will not be able to distinguish them. We need to be able to direct Django to the correct one. The simplest way to ensure this is through namespace. That is to say, place these templates in another directory named for the application itself.
Put the following code into the template file:
# polls/templates/polls/index.html{% 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 %}
Update the index view in polls/views. py to use the template:
# polls/views.pyfrom django.http import HttpResponsefrom django.template import RequestContext, loaderfrom .models import Questiondef index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] template = loader.get_template('polls/index.html') context = RequestContext(request, { 'latest_question_list': latest_question_list, }) return HttpResponse(template.render(context))
Load the template named polls/index.html and pass it a context. Context is a dictionary that maps the template variable name to a Python object.
Then you can open http: // 127.0.0.1: 8000/polls in the browser to view the effect.
Shortcut: render ()
A common habit is to load a template, fill in a context, and return an HttpResponse object containing the template rendering result. Django provides a shortcut for this purpose. The index () view after rewriting is shown below:
# polls/views.pyfrom django.shortcuts import renderfrom .models import Questiondef 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 complete this operation in all these views, we no longer need import loader and HttpResponse (if you still have the detail, results, and vote methods, you will need to keep HttpResponse ).
The render () function accepts the request object as its first parameter, the Template Name as its second parameter, and the dictionary as its optional third parameter. It returns an HttpResponse object containing the rendered template with the given context.
Error 404
Now let's process the view of the Question detail page -- display the page of the Question content:
# polls/views.pyfrom django.http import Http404from django.shortcuts import renderfrom .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})
The new concept here: if the problem with the requested ID does not exist, this view causes an Http404 exception.
We will discuss in the future what code you can put in the polls/detail.html template file, but if you want to run the above example quickly, you just need:
# polls/templates/polls/detail.html{{ question }}
Shortcut: get_object_or_404 ()
A common habit is to use get () and trigger Http404 when the object does not exist. Django provides a shortcut for this purpose. The detail () view after rewriting is shown below:
# polls/views.pyfrom django.shortcuts import get_object_or_404, renderfrom .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})
The get_object_or_404 () function uses a Django model as its first parameter, and any number of keyword parameters as its second parameter, it will pass these keyword parameters to the get () function in the model manager. If the object does not exist, an Http404 exception is thrown.
Why do we need to use a helper function get_object_or_404 () instead of automatically capturing ObjectDoesNotExist exceptions at a higher level, or causing the model API to trigger Http404 instead of ObjectDoesNotExist?
This will cause the model layer to be coupled with the view layer. One of Django's most important design goals is to maintain loose coupling. Some controllable coupling will be introduced in the django. shortcuts module.
There is also a get_list_or_404 () function, which works like get_object_or_404 ()-the difference is that it uses filter () instead of get (). If the list is empty, Http404 is triggered.
Use template System
Return to the detail () view of the voting application. According to the context variable question, the following is the possible appearance of the polls/detail.html template:
# polls/templates/polls/detail.html
The template system uses the dot search syntax to access variable attributes. In the {question. question_text} example, Django first looks up the problem of objects in a dictionary. If not, it tries an attribute query-in this case, it works. If the attribute search fails, it will try the List index search.
Method call occurred in the {% for %} loop: question. choice_set.all is interpreted as the Python code question. choice_set.all (), which returns an iteratable object consisting of Choice objects and uses it for the {% for %} tag. Visit the template guide to learn more