Published Date : 2019年10月5日7:42
前回からの続きです。
Continued from last time.
前回の記事の終わりにも書きましたが、今回はurls.pyの設定とtemplatesフォルダ内にtag.htmlを作り、タグ付けされた関連記事の表示をさせます。 それからindex.htmlとtag.htmlにタグリストを表示させて完了です。
As I wrote at the end of the last article, this time We'll settings urls.py and create a tag.html in the templates folder to display the tagged related articles. Then display the tag list on index.html and tag.html and it's done.
Demo Project demoblog __init__.py settings.py urls.py <- #今回、このurls.pyを書き換えます。 #This time, we will rewrite this urls.py. wsgi.py blogposts migrations static templates __init__.py admin.py apps.py models.py tests.py urls.py views.py <- #前回このviews.pyを書き換えました。 #We rewrote this views.py last time. db.sqlite3 manage.py
from django.conf.urls import include,url from django.conf.urls.static import static from posts import views urlpatterns = [ path('',views.index,name='index'), path('posts/',include('posts.urls')), path('posts/<post_id>/',views.post_detail,name="post_detail"), path('tag/<str:tagname>', views.related_posts, name="tagpost"), ###add ] + static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
path('tag/<str:tagname>', views.related_posts, name="tagpost")
path(URLのパスとパラメーター、指定したURLにアクセスがあった場合に動かすviews.pyの関数、Djangoテンプレートで使う名前)
path (The path and parameters of the URL, the views.py functions to run when the specified URL is accessed, and the name to use in the Django template)
Demo Project demoblog __init__.py settings.py urls.py wsgi.py blogposts migrations static templates index.html tag.html <- #new create __init__.py admin.py apps.py models.py tests.py urls.py views.py db.sqlite3 manage.py
<!DOCTYPE html> <html lang="ja-jp"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Demo Blog</title> <!-- Bootstrap and Font Awesome css cdn --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.0/css/bootstrap.min.css" integrity="sha384-PDle/QlgIONtM1aqA2Qemk5gPOE7wFq8+Em+G/hmo5Iq0CCmYZLv3fVRDJ4MMwEA" crossorigin="anonymous"> <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> <style> .breadcrumb{ background-color: white; } .breadcrumb-item + .breadcrumb-item::before { content: ">"; } </style> </head> <body> <!-- tag list --> <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <a class="navbar-brand" href="#">demo blog</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav mr-auto"> {% load indices %} {% for tag in tags %} <li class="nav-item"> <a class="nav-link" href="{% url 'tagpost' tag_names|indices:forloop.counter0 %}">{{ tag }}</a> </li> {% endfor %} </ul> </div> </nav> <!-- --> <!-- Breadcrumb --> <nav aria-label="breadcrumb"> <ol class="breadcrumb"> <li class="breadcrumb-item"><a title="Home" href="{% url 'index' %}"><i class="fa fa-home"> Home</i></a></li> <li class="breadcrumb-item active" aria-current="page"><a title="{{ tag_name }}" href="{% url 'tagpost' tag_name %}">tag > {{ tag_name }}</a></li> </ol> </nav> <!-- --> <!-- title list--> <div class="container text-center"> <br><br> <h1>{{ tag_name }}</h1> <br> <hr> {% for article in article_list.all %} <a href="{% url 'post_detail' article_url_indices|indices:forloop.counter0 %}">{{ article.title }}</a> <hr> {% endfor %} </div> <!-- --> <!-- JQuery and Bootstrap cdn --> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.0/js/bootstrap.min.js" integrity="sha384-7aThvCh9TypR7fIc2HV4O/nFMVCBwyIUKL8XCtKE+8xgCgl/PQGuFsvShjr74PBp" crossorigin="anonymous"></script> </body> </html>
殆どの処理はviews.pyで行っているが、ポイントとなるのはこの部分の記述。
Most of the processing is done by views.py, but the point is to describe this part.
{% url 'tagpost' tag_names|indices:forloop.counter0 %}
この「indices」の部分はカスタムフィルタと言って、簡単にいうとDjangoに足らない部分を補うために、自分で独自の関数を作ることをいう。
This "indices" part is called a custom filter, which simply means creating your own functions to compensate for the lack of Django.
Djangoのテンプレートに、Pythonの配列参照(array[1]=”ホゲ”)のような機能が無いので、これを作ります。
Django templates don't have the functionality of Python array references (array [1] = "hoge"), so I'll create them.
まずカスタムフィルタを置く場所、tempatetagsフォルダーを作ります。
First, create a tempatetags folder for your custom filters.
Demo Project demoblog __init__.py settings.py urls.py wsgi.py blogposts migrations static templates index.html tag.html templatetags <- #new create __init__.py admin.py apps.py models.py tests.py urls.py views.py db.sqlite3 manage.py
続いて、この「templatetags」ディレクトリの中のPythonファイルを、Djangoを動かしているPythonにパッケージとして認識させる為に、__init__.pyを作ります。
Next, create __init__.py to make Python on which Django is running recognize the Python files in this "templatetags" directory as packages.
この__init__.pyファイルの中には何も書かなくて大丈夫です。
You don't have to write anything in this __init__.py file.
Demo Project demoblog __init__.py settings.py urls.py wsgi.py blogposts migrations static templates index.html tag.html templatetags __init__.py <- #new create __init__.py admin.py apps.py models.py tests.py urls.py views.py db.sqlite3 manage.py
続いてindices.pyを作ります。
Next, create indices.py.
Demo Project demoblog __init__.py settings.py urls.py wsgi.py blogposts migrations static templates index.html tag.html templatetags __init__.py indices.py <- #new create __init__.py admin.py apps.py models.py tests.py urls.py views.py db.sqlite3 manage.py
from django import template register = template.Library() @register.filter def indices(py_list, idx): return py_list[int(idx)]
この関数の仕組みは単純。 Indices関数はPythonリストと別のリストのインデックス番号を引数として受け取ったら、 このリストの配列参照した値を返すだけです。
The mechanism of this function is simple. If the Indices function receives the index number of a Python list and another list as arguments, it simply returns the array referenced from that list.
このカスタムフィルタを使う際は先に
{% load indices %}と書いてロードします。
To use this custom filter, first load it with
{% load indices %}.
{% load indices %} {% for tag in tags %} <li class="nav-item"> <a class="nav-link" href="{% url 'tagpost' tag_names|indices:forloop.counter0 %}">{{ tag }}</a> </li> {% endfor %}
{% url 'tagpost' tag_names|indices:forloop.counter0 %}
url 'tagpost'はurls.pyに設定したURLを呼び出します。
The url 'tagpost' calls the URL you set in urls.py.
このURLは<str型>のパラメータを受け取りますので、先程作ったカスタムフィルタを使って引数として渡します。
This URL takes a <str type> parameter, which you pass as an argument using the custom filter you just created.
tag_names|indices:forloop.counter0
この部分を馴染みのあるPython文法に直すと、こうなります。
If you translate this code into the familiar Python grammar, you get this.
for idx, tag in enumerate(tags): print(indices(tag_names, idx)) --> def indices(tag_names, idx): return tag_names[int(idx)] --> """ >>> tag_names[1] --> 'Python' """ --> """ url 'tagpost' """ --> """ http://example.com/tag """ --> """ url 'tagpost' 'Python' """ --> """ http://example.com/tag/Python """
最後にindex.htmlにタグリスト表示機能を付け加えれば完成です。
Finally, add the tag list display function to index.html and you're done.
Demo Project demoblog __init__.py settings.py urls.py wsgi.py blogposts migrations static templates index.html <- #add features to tag.html templatetags __init__.py indices.py __init__.py admin.py apps.py models.py tests.py urls.py views.py db.sqlite3 manage.py
<!DOCTYPE html> <html lang="ja-jp"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Demo Blog</title> <!-- Bootstrap and Font Awesome css cdn --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.0/css/bootstrap.min.css" integrity="sha384-PDle/QlgIONtM1aqA2Qemk5gPOE7wFq8+Em+G/hmo5Iq0CCmYZLv3fVRDJ4MMwEA" crossorigin="anonymous"> <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> <style> .breadcrumb{ background-color: white; } .breadcrumb-item + .breadcrumb-item::before { content: ">"; } </style> </head> <body> <!-- tag list --> <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <a class="navbar-brand" href="#">demo blog</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav mr-auto"> {% load indices %} {% for tag in tags %} <li class="nav-item"> <a class="nav-link" href="{% url 'tagpost' tag_names|indices:forloop.counter0 %}">{{ tag }}</a> </li> {% endfor %} </ul> </div> </nav> <!-- --> <!-- Breadcrumb --> <nav aria-label="breadcrumb"> <ol class="breadcrumb"> <li class="breadcrumb-item active"><a title="Home" href="{% url 'index' %}"><i class="fa fa-home"> Home</i></a></li> </ol> </nav> <!-- --> <!-- title list--> <h1>demo blog title</h1> <br /><br /> {% load static %} <img src="{% static "posts/001.jpg" %}" class="img-fluid rounded" alt="Responsive image"/> <hr> <br /><br /> {% for post in posts.all %} <br /><br /> <h4><a href="{% url 'post_detail' post.id %}">{{post.title}}</a></h4> {{post.published}} <br /><br /> <hr> {% endfor %} <!-- JQuery and Bootstrap cdn --> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.0/js/bootstrap.min.js" integrity="sha384-7aThvCh9TypR7fIc2HV4O/nFMVCBwyIUKL8XCtKE+8xgCgl/PQGuFsvShjr74PBp" crossorigin="anonymous"></script> </body> </html>
これでホームの記事一覧ページのナビバーに、タグリストが表示され、 タグをクリックすると、そのタグに関連付けされた記事の一覧のページに飛べるようになります。
Now, in the navigation bar of your home article list page, you'll see a tag list that you can click to go to the article list page associated with that tag.
あとは各々で色々試行錯誤して見やすいように、使いやすいようにカスタマイズしてくだちぃ。
Then, customize it so that it is easy to use and see through trial and error.