Published Date : 2019年10月4日13:32

Djangoで作ったブログのタグリストから関連記事を表示させる(1)
Show related articles from the tag list of Django blogs(1)


This blog has an English translation



前回作ったタグリストから、そのタグに応じた関連記事を表示させていきます。

From the list of tags you created last time, you can display related articles according to the tags.

タグリストはサイドバー領域に設置することが多いみたいです。

Tag lists are often placed in the sidebar area.



Responsive image


ですが、自分はナビバー領域に表示させることにしました。

But I decided to display it in the Navi Bar area.



Responsive image


何故かというと、スマホ等の幅が狭いデバイスで見た場合、通常ナビバーの項目は折り畳まれて表示されない為、スッキリとした見た目になるからです。

That's because when viewed on a narrow device like a smartphone, the items on the navigation bar usually don't fold up and appear slimmer.



Responsive image




Responsive image



views.pyの設定
Configuring views.py

views.pyにタグリストのオブジェクトから必要な情報を取得する関数を作る。

Create a function in views.py that retrieves the required information from the object in the tag list.

Demo Project
    demoblog
        __init__.py
        settings.py <- #INSTALLED_APPSはこの中にあります。
                       #INSTALLED_APPS is located here.
        urls.py
        wsgi.py
    blogposts
        migrations
        static
        templates
        __init__.py
        admin.py
        apps.py
        models.py <- #前回このmodels.pyを書き換えました。
                     #We rewrote this models.py last time.
        tests.py
        urls.py
        views.py <- #今回、このviews.pyを書き換えます。
                    #This time, we will rewrite this views.py.
    db.sqlite3
    manage.py

views.py
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from .models import Post

from taggit.models import Tag ##add

def index(request):
    posts = Post.objects.order_by('-published')
    
    tags, tag_names = tag_list() ##add

    context = {
        'posts':posts,
        'tags':tags,
        'tag_names':tag_names,
        }

    return render(request,'posts/index.html', context)

## add
def tag_list():
    tags = Tag.objects.all()
    tag_names = [tag_name for tag_name in tags] 
    return tags, tag_names

## add
def related_posts(request, tagname):

    tags, tag_names = tag_list()

    tag_name = get_object_or_404(Tag, name = tagname)
    article_list = Post.objects.filter(tags = tag_name)

    posts = Post.objects.order_by('-published')
    posts_ids_titles = { idx+1:post.title for idx,post in enumerate(reversed(posts)) }

    article_url_indices = []
    for key,value in posts_ids_titles.items():
        for article in article_list.all():
            if article.title == value:
                article_url_indices.append(key)
                break
        
    context = {
        'tag_name':tag_name,
        'article_list':article_list,
        'tags':tags,
        'tag_names':tag_names,
        'article_url_indices':article_url_indices,
        }

    return render(request, 'posts/tag.html', context)

処理内容は、tag_list()でタグオブジェクト(queryset)とタグの名前を取得して、全ページのナビバーで使えるようにする。

The tag _ list() gets the tag object (queryset) and the name of the tag so that it can be used in the navigation bar on all pages.

related_posts()で'posts/tag.html'にタグ付けされた関連記事を表示させる。

Show related posts tagged with 'posts/tag.html' in related_posts().


related_posts()の中身の説明
A description of the contents of related_posts().

def related_posts(request, tagname):

引数にタグの名前を受け取る。

Takes the name of the tag as an argument.

tags, tag_names = tag_list()

作って置いたtag_list関数からタグオブジェクトとタグの名前のリストを受け取る。

It receives a list of tag objects and tag names from the created tag _ list function.

tag_name = get_object_or_404(Tag, name = tagname)
article_list = Post.objects.filter(tags = tag_name)

ユーザーから指定されたタグの名前(例えばPython等)からそのタグに関連付けされた記事だけ取り出す。

Only the articles associated with the tag are retrieved from the name of the tag specified by the user (e.g. Python, etc.).

posts = Post.objects.order_by('-published')
posts_ids_titles = { idx+1:post.title for idx,post in enumerate(reversed(posts)) }

自分のブログの各ページのURLはページ番号を頼りに参照しているので、 二度手間だが、一度記事全体を取り出して、タイトルとページ番号を辞書にする。

The URL of each page of my blog depends on the page number. It takes two steps, but it takes the entire article and turns the title and page number into a dictionary.

article_url_indices = []
for key,value in posts_ids_titles.items():
    for article in article_list.all():
        if article.title == value:
            article_url_indices.append(key)
            break

タグから取り出した記事一覧のページ番号はバラバラになっているので、 上手くアンカータグによってリンクできるように、記事のタイトルを頼りに、URLの番号を合わせる。

The page numbers of the list of articles taken out from the tag are separated. In order to link well with anchor tags, the article's title is used to match the number of the URL.

context = {
    'tag_name':tag_name,
    'article_list':article_list,
    'tags':tags,
    'tag_names':tag_names,
    'article_url_indices':article_url_indices,
    }

return render(request, 'posts/tag.html', context)

関数内の変数を全てまとめ、render関数を使って'posts/tag.html'に渡してあげる。

Put all the variables in the function together and pass them to 'posts/tag.html' using the render function.


次回へ続く
To be continued next time

次回はurls.pyの設定とtemplatesフォルダ内にtag.htmlを作り、index.htmlとtag.htmlにDjangoテンプレートで タグリストと、タグ付けされた関連記事の表示をさせていきます。

Next time, we'll set up urls.py and create tag.html in the templates folder, then add index.html and tag.html with the Django template. You'll see a list of tags and associated articles.




See You Next Page!