Writing your first Django app, part 3¶This tutorial begins where Tutorial 2 left off. We’re continuing the web-poll application and will focus on creating the public interface – “views.” Show
Where to get help: If you’re having trouble going through this tutorial, please head over to the Getting Help section of the FAQ. Overview¶A view is a “type” of web page in your Django application that generally serves a specific function and has a specific template. For example, in a blog application, you might have the following views:
In our poll application, we’ll have the following four views:
In Django, web pages and other content are delivered by views. Each view is represented by a Python function (or method, in the case of class-based views). Django will choose a view by examining the URL that’s requested (to be precise, the part of the URL after the domain name). Now in your time on the web you may have come across such beauties as A URL pattern is the general form of a URL - for example:
To get from a URL to a view, Django uses what are known as ‘URLconfs’. A URLconf maps URL patterns to views. This tutorial provides basic instruction in the use of URLconfs, and you can refer to URL dispatcher for more information. Writing more views¶Now let’s add a few more views to
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) Wire these new views into the
from django.urls import path from . import views urlpatterns = [ # ex: /polls/ path('', views.index, name='index'), # ex: /polls/5/ path('<int:question_id>/', views.detail, name='detail'), # ex: /polls/5/results/ path('<int:question_id>/results/', views.results, name='results'), # ex: /polls/5/vote/ path('<int:question_id>/vote/', views.vote, name='vote'), ] Take a look in your browser, at “/polls/34/”. It’ll run the When somebody requests a page from your website – say, “/polls/34/”, Django will load the detail(request=<HttpRequest object>, question_id=34) The Write views that actually do something¶Each view is responsible for doing one of two things: returning an
Your view can read records from a database, or not. It can use a template system such as Django’s – or a third-party Python template system – or not. It can generate a PDF file, output XML, create a ZIP file on the fly, anything you want, using whatever Python libraries you want. All Django wants is that Because it’s convenient, let’s use Django’s own database API, which we covered in
Tutorial 2. Here’s one stab at a new
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’s a problem here, though: the page’s design is hard-coded in the view. If you want to change the way the page looks, you’ll have to edit this Python code. So let’s use Django’s template system to separate the design from Python by creating a template that the view can use. First, create a directory called Your project’s Within the Template namespacing Now we might be able to get away with putting our templates directly in Put the following code in that template:
{% 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 %} Note To make the tutorial shorter, all template examples use incomplete HTML. In your own projects you should use complete HTML documents. Now
let’s update our
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)) That code loads the template called Load the page by pointing your browser at “/polls/”, and you should see a bulleted-list containing the “What’s up” question from Tutorial 2. The link points to the question’s detail page. A shortcut: render()¶It’s a very common idiom to load a template, fill a context and return an
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’ve done this
in all these views, we no longer need to import The
Raising a 404 error¶Now, let’s tackle the question detail view – the page that displays the question text for a given poll. Here’s the view:
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}) The new concept here: The view raises the We’ll discuss what you could put in that
will get you started for now. A shortcut: get_object_or_404()¶It’s a very common idiom to use
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}) The Philosophy Why do we use a helper function
Because that would couple the model layer to the view layer. One of the foremost design goals of Django is to maintain loose coupling. Some controlled
coupling is introduced in the There’s also a Use the template system¶Back to the
<h2>{{ question.question_text }}</h2> <ul> {% for choice in question.choice_set.all %} <li>{{ choice.choice_text }}</li> {% endfor %} </ul> The
template system uses dot-lookup syntax to access variable attributes. In the example of Method-calling happens in the See the template guide for more about templates. Removing hardcoded URLs in templates¶Remember, when we wrote the link to a question in the <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li> The problem with this hardcoded, tightly-coupled approach is that it becomes challenging to change URLs on projects with a lot of templates. However, since you defined the name
argument in the <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li> The way this works is by looking up the URL definition as specified in the ... # the 'name' value as called by the {% url %} template tag path('<int:question_id>/', views.detail, name='detail'), ... If you want to change the URL of the polls detail view to something else, perhaps to something like ... # added the word 'specifics' path('specifics/<int:question_id>/', views.detail, name='detail'), ... Namespacing URL names¶The tutorial project has just one app, The answer is to add namespaces to your URLconf. In the
from django.urls import path from . import views app_name = 'polls' urlpatterns = [ path('', views.index, name='index'), path('<int:question_id>/', views.detail, name='detail'), path('<int:question_id>/results/', views.results, name='results'), path('<int:question_id>/vote/', views.vote, name='vote'), ] Now change your
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li> to point at the namespaced detail view:
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li> When you’re comfortable with writing views, read part 4 of this tutorial to learn the basics about form processing and generic views. When working with forms which of the following views would you use if you want to alter the design of a form and see the effects of the changes in real time?Layout view and Design view are the two views in which you can make design changes to forms.
Which of the following is used to find data in a database?Queries. Queries can perform many different functions in a database. Their most common function is to retrieve specific data from the tables.
Which of the following is used for when you want to organize and summarize your data in a report?Which of the following is useful when you want to organize and summarize you data? To organize controls vertically on a form, use a tabular layout.
Which View is used to make design changes to a form while the form is displaying data?In Layout view, you can make design changes to the form while it is displaying data. When you use the Multiple Items tool, the form that Access creates resembles a datasheet. The data is arranged in rows and columns, and you see more than one record at a time.
|