[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-Part 4-

Introduction

Nice to meet you, everyone. I'm going to publish a memorandum of the process of creating a voting (poll) application using Django. Since I am a beginner of Qiita, please understand that some parts may be difficult to read.

series

-[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-No. 0- -[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-Part 1- -[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-Part 2- -[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-Part 3-

Start work

Write a simple form

I will write the form in HTML.

Voting view

Description of form tag

--action: URL to send data --method: Data transmission method (get, post)

Description of input tag

--type: Radio button (radio), submit button (submit) --value: current value --id: ID that identifies the button

"{% Csrf_token%}" is a cross-site request forgery countermeasure mechanism provided by Django. Since we are using the POST method, we will use csrf_token.

polls/template/polls/detail.html


<h1>{{ question.question_text }}</h1>
{% if error_message %}<p><strong>{{error_message}}</strong></p>{% endif %}
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
    <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
    <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
{% endfor %}
<input type="submit" value="Vote">
</form>

Access the POST data choice with "request.POST ['choice']". Returns KeyError if there is no choice in the POST data

If an exception occurs, the question form will be displayed again with an error.

"Reverse ('polls: results', args = (question.id))" returns polls / urls.py> path function (name ='results').

:polls/views.py

from django.http import HttpResponse, Http404, HttpResponseRedirect
from .models import Question, Choice
from django.shortcuts import render, get_object_or_404
from django.urls import reverse

def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        return render(request, 'polls/detail.html',
                      {'question': question,
                       'error_message': "You didn't select a choice."})
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

It is OK if you access "http://127.0.0.1:8000/polls/ " and the form screen is displayed.

image.png

Result view

polls/template/polls/results.html



<h1>{{ question.question_text }}</h1>

<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
<ul>

<a href="{% url 'polls:detail' question.id %}">Vote again?</a>

polls/views.py



from django.http import Http404, HttpResponseRedirect

def results(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/results.html', {'question': question})

Select an option on the "http://127.0.0.1:8000/polls/ " form screen and press the Vote button to move to the screen below. image.png

Use generic view: less code is good

We will continue to reduce the code. In particular, we will eliminate redundant parts.

These views represent the general case of basic web development. That is, it retrieves data from the database according to the parameters passed through the URL, loads the template, and returns the rendered template. This is so common that Django offers a shortcut called the generic view. A generic view is an abstraction of a common pattern that allows you to write an application without even writing Python code.

Modify URLconf

Only name = detail and results should be changed from "<int: questioniopkn_id>" to "<int: pk>". This is because it uses the DetailView, which will be explained later. name = index, detail, results will create a class later, so let's say "views. ** View.as_view ()"

polls/urls.py



    path('', views.IndexView.as_view(), name='index'),
    path('<int:pk>/', views.DetailView.as_view(), name='detail'),
    path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
    path('<int:questiopkn_id>/vote/', views.vote, name='vote'),

Modify views

views.py changes a lot. I used to use functions a lot in def, but I use class.

--ListView The generic view uses the " / _list.html" template and passes the " _list" context variable for lettering. If you use the template_name attribute, the specified template will be used. The context_object_name attribute causes the specified context variable to be used.

--DetailView The general view uses the " / _detail.html" template and passes the "" context variable for lettering. If you use the template_name attribute, the specified template will be used. The context_object_name attribute causes the specified context variable to be used. As specified in urls.py, it has a mechanism to read the primary key from the URL with the name "pk".

polls/views.py



# Create your views here.
from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.urls import reverse
from django.views import generic

from .models import Question, Choice


class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'

    def get_queryset(self):
        return Question.objects.order_by('-pub_date')[:5]


class DetailView(generic.DetailView):
    model = Question
    template_name = 'polls/detail.html'


class ResultsView(generic.DetailView):
    model = Question
    template_name = 'polls/results.html'


def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

That's all for today. Thank you very much.

Recommended Posts

[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-Part 7-
[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-Part 1-
[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-Part 2-
[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-Part 0-
[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-Part 5-
[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-Part 6-
[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-Part 4-
[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-Part 3-
Django python web framework
Deploy a Python 3.6 / Django / Postgres web app on Azure
(Python) Try to develop a web application using Django
CTF beginner tried to build a problem server (web) [Problem]
Web scraping beginner with python
[Django3] Display a web page in Django3 + WSL + Python virtual environment
A liberal arts engineer tried knocking 100 language processes in Python 02
A python beginner tried to intern at an IT company
A liberal arts engineer tried knocking 100 language processes in Python 01
A liberal arts engineer tried knocking 100 language processes in Python 00
If you know Python, you can make a web application with Django
[Python / Django] Create a web API that responds in JSON format
I tried web scraping with python.
Build a web application with Django
Python beginner tried 100 language processing knock 2015 (05 ~ 09)
web coder tried excel in Python
When a Python beginner tried using Bottle, it worked unexpectedly easily.
Python beginner tried 100 language processing knock 2015 (00 ~ 04)
A beginner of machine learning tried to predict Arima Kinen with python
An introduction to self-made Python web applications for a sluggish third-year web engineer
A note where a Python beginner got stuck
[Beginner] Python web scraping using Google Colaboratory
I have a question! (Python, django) Easy
Daemonize a Python web app with Supervisor
I tried a functional language with Python
[Python] A quick web application with Bottle!
I tried to make a Web API
Use Django from a local Python script
Run a Python web application with Docker
Let's make a web framework with Python! (1)
I tried benchmarking a web application framework
Let's make a web framework with Python! (2)
I made a WEB application with Django
A python beginner tried to intern at an IT company [Day 2 chatbot survey]
A python beginner tried to intern at an IT company [Day 1 development process]
Go beginner tried to create a cloud native web application using Datastore / GAE
[ES Lab] I tried to develop a WEB application with Python and Flask ②
I searched for the skills needed to become a web engineer in Python
Machine learning memo of a fledgling engineer Part 1
2-2. Input for becoming a WEB engineer (Linux basics)
How to open a web browser from python
I tried web scraping using python and selenium
Python web framework Django vs Pyramid vs Flask December 2015
I tried playing a typing game in Python
Start a simple Python web server with Docker
[Memo] I tried a pivot table in Python
Steps to develop a web application in Python
[Python] Web development preparation (building a virtual environment)
I tried reading a CSV file using Python
Launch a web server with Python and Flask
Machine learning memo of a fledgling engineer Part 2
Run a Python file from html using Django
I tried adding a Python3 module in C