Python Django Tutorial (3)

This is a material for study sessions. I will explain while following the tutorial of django1.8. https://docs.djangoproject.com/en/1.8/intro/tutorial03/

Since version 1.4 is the latest version of the official Japanese document, there are some differences, but the general flow is the same, so it's a good idea to read it. http://django-docs-ja.readthedocs.org/en/latest/intro/tutorial03.html

Tutorial 1 Tutorial 2Tutorial Summary

Overview

In this tutorial, we will explain view and url. Although it is called view, it is equivalent to a controller in general MVC. The equivalent of MVC View is a template called from view.

I'm talking about MVC a little bit, so please listen lightly.

Create view and connect url

Documents → https://docs.djangoproject.com/en/1.8/intro/tutorial03/#write-your-first-view Source → 7f5128a 3efdc15

In this tutorial, we will explain the 5th to 7th parts of application creation explained in tutorial (1).

Before that, I will explain the flow of creating an application with django.

  1. Add an application with $ ./manage.py startapp appname.
  1. Describe the model (database table) used in the application in ʻappname / models.py`.
  1. Add the created app to project / settings.py
  1. Database update
  1. Describe the model display and operation (addition, editing, etc.) in ʻappname / views.py`. The html to be used is also prepared here.
  2. Describe ʻappname / urls.py` and associate url and views
  3. Read ʻappname / urls.py from project / urls.py`.

Add view

view is a function that receives HttpRequest and returns HttpResponse.

Let's write the view function by following the original tutorial.

polls/views.py


from django.http import HttpResponse


def index(request):
    return HttpResponse("Hello, world. You're at the polls index.")

The view method always receives the HttpRequest class as the first argument. Also, it is necessary to return the HttpResponse class (or a class that inherits it) as a return value.

Of course, you can't understand the operation from this alone, so let's connect the url and view.

url setting

The url setting method and concept have changed significantly in django1.8, so please be careful if you are proceeding while watching the original Japanese tutorial (django1.4).

When accessing django, first check ROOT_URLCONF (project / urls.py by default, tutorial / urls.py in this tutorial) to see which view to call.

An array called ʻurlpatterns` is set in urls.py. Array elements are added with the url function.

The content is ʻurl resolver`, but I will omit it because it will be a maniac story.

The url function associates url with view, or url with other url patterns.

Let's actually look at the source.

polls/urls.py


from django.conf.urls import url

from . import views


urlpatterns = [
    url(r'^$', views.index, name='index'),  #Linking url and view
]

At this stage polls.views.index and polls urls are connected, but polls.urls is not root_url It cannot be confirmed from the browser yet.

tutorial/urls.py


from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^polls/', include('polls.urls')),  #Linking urls with other url patterns
]

The root_url has been updated. Now the url that matches polls / will call polls.urls and you can see it in your browser.

Let's access http: // localhost: 8000 / polls /.

Kobito.JVhyfF.png

It seems that the connection is successful.

url function

In the url function, describe the regular expression of url in the first argument, and pass the return value of the view function or include function in the second argument. It may be mistaken for a regular expression if you write> r'', but it is a raw string.

\ Will be output as it is instead of the escape character. The third argument, name ='index'), is for reverse lookup of the url. It is used for redirecting to another view and linking in template.

When include is used, the part where the matched character string is removed is passed to the next urlpatterns.

Use of template

Documents → https://docs.djangoproject.com/en/1.8/intro/tutorial03/#a-shortcut-render Source → 3efdc15 18eb3f6

I was able to connect the url and view successfully, but I don't have much handwriting for the Response string. Next, let's use template.

Template is installed under ʻapp / templates / app /. The format is almost the same as general html, but if you enclose it in two curly braces like {{var}} You can use the value passed from python. You can also execute a function called a template tag in the format{% func%}`.

First, create it using normal html.

polls/templates/polls/index.html


<html>
<body>
  <p>Hello, world. You're at the polls index.</p>
  <p>template version!</p>
</body>
</html>

Then rewrite the view. The original tutorial introduces how to create a character string using template, but This time, I will show you how to skip it and use the render function. This function will give you a request, a template path and the rendering result using that template It will be returned as HttpResponse. Change the source as follows and check it with a browser.

polls/views.py


from django.shortcuts import render


def index(request):
    return render(request, 'polls/index.html')

Kobito.W5zmjU.png

It seems that it returns a character string using template properly.

Passing by value to template

Source → 1ade762 c49d0c6

By now, you should be able to create static pages. Next, let's create a dynamic page. You can pass a value to template by passing a dictionary as the third argument of render. When using the value passed in the template, write it in the format {{var}}.

Let's rewrite the view and pass an appropriate value.

polls/views.py


from django.shortcuts import render


def index(request):
    return render(request, 'polls/index.html', {
        'hoge': 'test string',
        'fuga': '<br>tag</br>',
    })

Next, rewrite the html and display the received value.

polls/templates/polls/index.html


<html>
<body>
  <p>Hello, world. You're at the polls index.</p>
  <p>template version!</p>
  <p>{{ hoge }}</p>
  <p>{{ fuga }}</p>
</body>
</html>

Kobito.glaQa6.png

It seems that the received value is displayed properly. However, in fuga, the <br> tag has been escaped and output. I'm happy about security, but I'm in trouble when I want to output tags. Use the django.utils.html.mark_safe function to output tags. As the name implies, this function marks the string as safe and prevents it from being escaped anymore.

Let's pass a new character string with mark_sake to piyo and output it.

polls/views.py


from django.shortcuts import render
from django.utils.html import mark_safe


def index(request):
    return render(request, 'polls/index.html', {
        'hoge': 'test string',
        'fuga': '<br>tag</br>',
        'piyo': mark_safe('<br>tag</br>'),
    })

polls/templates/polls/index.html


<html>
<body>
  <p>Hello, world. You're at the polls index.</p>
  <p>template version!</p>
  <p>{{ hoge }}</p>
  <p>{{ fuga }}</p>
  <p>{{ piyo }}</p>
</body>
</html>

Kobito.8qg0k1.png

It seems that the piyo tag was output without being escaped.

Cooperation with the model

Source → c49d0c6 95339e5

Now that I'm pretty happy with the string, let's display the Question model. That said, you just pass an instance of the model or a query set instead of a string. A detailed explanation of the query set will be given later. For now, keep in mind that you can get the query set for that model with Model.objects.

If you want to know immediately, please refer to the original document. → https://docs.djangoproject.com/en/1.8/ref/models/querysets/

Let's try passing all the objects of the Question model to the template with the name questions.

polls/views.py


from django.shortcuts import render

from .models import Question


def index(request):
    return render(request, 'polls/index.html', {
        'questions': Question.objects.all(),
    })

Let's display it in html and check it with a browser.

polls/templates/polls/index.html


<html>
<body>
  {{ questions }}
</body>
</html>

Kobito.nM35Me.png

It's a little uncool, but it seems to come out properly.

Modify template display

Source → 95339e5 943e24b

Since questions are arrays, use the {% for%} function provided as standard in the template to improve the appearance.

polls/templates/polls/index.html


<html>
<body>
  <table border="1">
    <tr>
      <th>Contents of question</th>
      <th>release date</th>
    </tr>
    {% for question in questions %}
    <tr>
      <td>{{ question.question_text }}</td>
      <td>{{ question.pub_date }}</td>
    </tr>
    {% endfor %}
  </table>
</body>
</html>

Kobito.LmxoBX.png

It looks like that.

Add detail screen

Source → 943e24b → ʻe86d795`

The list screen is good for the time being, but let's create an individual detail screen this time. The flow is the same, just prepare a view and connect the url, Since it is a detail screen, it is necessary to specify a specific object in the model. This time, as a general method of django, we will receive the pk of the object.

The view looks like this.

polls/views.py


...
def detail(request, pk):
    return render(request, 'polls/detail.html', {
        'question': Question.objects.get(pk=pk)
    })

Don't forget to prepare detail.html called from view.

polls/templates/polls/detail.html


<html>
<body>
  {{ question }}
</body>
</html>

Then change the url. The url can be passed to the view function as an argument in the form of (? P <kwarg> pattern).

polls/urls.py


...
urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'(?P<pk>\d+)/$', views.detail, name='poll_detail'),
]

In this case, like http: // localhost: 8000 / polls / 1 / or http: // localhost: 8000 / polls / 3 / It means that the numbers 1 and 3 are passed to the detail function as an argument of pk.

Kobito.WlPWYR.png

Kobito.cJ7N4Z.png

The details page is complete.

Added 404 pages

Source → ʻe86d795da8d171`

The details screen has been created, but if you enter a non-existent pk such as 10 in the URL, the screen will look like the one below.

Kobito.mFw3WE.png

The Model.objects.get method throws an exception DoesNotExist when the object cannot be acquired under the specified conditions, resulting in a screen like this. Since the return value of the view function must be HttpResponse, let's modify it so that it catches the exception and displays page 404.

polls/views.py


from django.shortcuts import Http404
...
def detail(request, pk):
    try:
        obj = Question.objects.get(pk=pk)
    except Question.DoesNotExist:
        raise Http404
    return render(request, 'polls/detail.html', {
        'question': obj,
    })

It seems that you are throwing an Http404 exception instead of HttpResponse, but If you raise an Http404 exception, middleware will catch it and create a page for your 404.

Kobito.fcoOLN.png

A little more convenient 404 page

Source → da8d171 2b823b3

Since it is a general operation to try to get an object with a primary key etc. and return 404 if it does not exist A convenient shortcut function is provided. You can write the same operation as you did with try-except just by writing from which model and under what conditions.

polls/views.py


from django.shortcuts import get_object_or_404
...
def detail(request, pk):
    obj = get_object_or_404(Question, pk=pk)
    return render(request, 'polls/detail.html', {
        'question': obj,
    })

Connection from list page to detail screen

Documents → https://docs.djangoproject.com/en/1.8/intro/tutorial03/#removing-hardcoded-urls-in-templates Source → 2b823b3 99b01e3

Now that the list page and details screen have been created, let's put a link from the list page to the details screen. Use the {% url%} tag to embed a link in html. It will generate a url by passing the name of the url as an argument of this tag. The url name </ b> here is the name ='hoge' specified in the third argument of the url function.

In the tutorials so far, we have set the names ʻindex and poll_detail`. This time, we will create a link to poll_detail in index.html. Note that poll_detail needs to receive the pk of the question object as an argument.

polls/templates/polls/index.html


<html>
<body>
  <table border="1">
    <tr>
      <th>Contents of question</th>
      <th>release date</th>
      <th></th>
    </tr>
    {% for question in questions %}
    <tr>
      <td>{{ question.question_text }}</td>
      <td>{{ question.pub_date }}</td>
      <td><a href="{% url 'poll_detail' question.pk %}">To detail screen</a></td>
    </tr>
    {% endfor %}
  </table>
</body>
</html>

Kobito.hqbo81.png

The link to the details screen has been successfully posted.

Also, let's put a link from the details screen to the list screen.

polls/templates/polls/detail.html


<html>
<body>
  <a href="{% url 'index' %}">To the list screen</a><br>
  {{ question }}
</body>
</html>

Kobito.AvWWsf.png

Now you don't have to type the URL directly.

-- The order of the tutorial and the explanation of the original family was a little different, but in the next tutorial, we will deal with forms.

To the next tutorial

Tutorial Summary

Recommended Posts

Python Django Tutorial (5)
Python Django Tutorial (2)
Python Django Tutorial (8)
Python Django Tutorial (6)
Python Django Tutorial (7)
Python Django Tutorial (1)
Python Django tutorial tutorial
Python Django Tutorial (3)
Python Django Tutorial (4)
Python tutorial
Python Django Tutorial Cheat Sheet
Python tutorial summary
django tutorial memo
Start Django Tutorial 1
Django 1.11 started with Python3.6
[Docker] Tutorial (Python + php)
Django python web framework
Django Polymorphic Associations Tutorial
django oscar simple tutorial
Django Python shift table
Try Debian + Python 3.4 + django1.7 ...
[Personal notes] Python, Django
Python OpenCV tutorial memo
[Python tutorial] Data structure
Django Girls Tutorial Note
Cloud Run tutorial (python)
Python Django CSS reflected
Get started with Django! ~ Tutorial ⑤ ~
Introduction to Python Django (2) Win
[Python tutorial] Control structure tool
Do Django with CodeStar (Python3.8, Django2.1.15)
Python3 + Django ~ Mac ~ with Apache
Create ToDo List [Python Django]
Getting Started with Python Django (1)
Get started with Django! ~ Tutorial ④ ~
Django
Getting Started with Python Django (4)
Getting Started with Python Django (3)
Install Python 3.7 and Django 3.0 (CentOS)
[Python] Decision Tree Personal Tutorial
GAE + python + Django addictive story
Getting Started with Python Django (6)
Getting Started with Python Django (5)
Until Python [Django] de Web service is released [Tutorial, Part 1]
EEG analysis in Python: Python MNE tutorial
8 Frequently Used Commands in Python Django
Python practice_Virtual environment setup ~ Django installation
Create new application use python, django
python + django + scikit-learn + mecab (1) on heroku
Run python3 Django1.9 with mod_wsgi (deploy)
Django Girls Tutorial Summary First Half
Stumble when doing the django 1.7 tutorial
Deploy the Django tutorial to IIS ①
Install Python framework django using pip
Introduction to Python Django (2) Mac Edition
[Python Tutorial] An Easy Introduction to Python
Learning history for participating in team app development in Python ~ Django Tutorial 5 ~
Learning history for participating in team app development in Python ~ Django Tutorial 4 ~
Learning history for participating in team app development in Python ~ Django Tutorial 1, 2, 3 ~
Learning history for participating in team app development in Python ~ Django Tutorial 7 ~
Django Crispy Tutorial (Environment Building on Mac)