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 2 → Tutorial Summary
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.
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.
$ ./manage.py startapp appname
.project / settings.py
from
project / urls.py`.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.
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 /.
It seems that the connection is successful.
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.
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')
It seems that it returns a character string using template properly.
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>
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>
It seems that the piyo tag was output without being escaped.
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>
It's a little uncool, but it seems to come out properly.
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>
It looks like that.
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.
The details page is complete.
Source → ʻe86d795→
da8d171`
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.
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.
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,
})
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>
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>
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.
Recommended Posts