Django Views - index and template

Posted under » Django on 6 May 2021

A view is a “type” of Web page in your Django application that generally serves a specific function and has a specific template. This is different from Cakephp or Symfony where a view is a template. A view is like a controller in Django.

Now let’s add a few more views to polls/views.py.

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 polls.urls module by adding the following path() calls:

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 detail() method and display whatever ID you provide in the URL. Try “/polls/34/results/” and “/polls/34/vote/” too – these will display the placeholder results and voting pages.

Take note that if you type “/polls/34” you will get 404 error. You will need to put the trailing /.

Now lets change the index page to something meaningful. There’s a problem here, though: the page’s design was hard-coded in the view.

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))

or a shortcut

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)

So let’s use Django’s template system to separate the design from Python by creating a template that the view can use.

Put the following code in that template "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.

{% endif %}

The problem with this hardcoded, tightly-coupled approach is that it becomes challenging to change URLs on projects with a lot of templates. Read the solution in URL namespace

Now let's tackle the details page.

web security linux ubuntu python django git Raspberry apache mysql php drupal cake javascript css AWS