###1.簡単な投稿機能を作成
#####構造
mysite
├─mysite
│ └─__pycache__
├─post
│ ├─migrations
│ │ └─__pycache__
│ └─__pycache__
└─templates
mysite/post/models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=20)
text = models.CharField(max_length=200)
def __str__(self):
return self.title
mysite/post/views.py
from django.views.generic import ListView, CreateView
from django.urls import reverse_lazy
from .models import Post
class ListClass(ListView):
template_name = 'list.html'
model = Post
class FormClass(CreateView):
template_name = 'form.html'
model = Post
fields = ('title', 'text')
success_url = reverse_lazy('list')
mysite/post/urls.py
from django.urls import path
from .views import FormClass, ListClass
urlpatterns = [
path('', ListClass.as_view(), name='list'),
path('form/', FormClass.as_view(), name='form'),
]
templatesファイルを作るのでsettings.py
のTEMPLATEを設定する
'DIRS': [BASE_DIR, 'templates'],
mysite/templates/form.html
<form method="POST">
{% csrf_token %}
<p>タイトル<br /><input type="text" name="title" /></p>
<p>
内容<br /><textarea type="text" name="text" rows="10" cols="40"></textarea>
</p>
<input type="submit" value="投稿する" />
</form>
mysite/templates/list.html
<div class="container">
{% for post in object_list %}
<div class="post">
<p>タイトル<br/>{{ post.title }}</p>
<p>内容<br/>{{ post.text|linebreaksbr }}</p>
<p>--------------------</p>
</div>
{% endfor %}
<div class="form">
<a href="{% url 'form' %}">新規投稿</a>
</div>
</div>
###2.タグ機能を実際に作っていく
mysite/post/models.py
from django.db import models
class Tag(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=20)
text = models.CharField(max_length=200)
tag = models.ManyToManyField(Tag)
def __str__(self):
return self.title
tagクラスを作り、postクラスと結びつけた
postクラスはたくさんのタグを持つことができる
mysite/post/views.py
from django.views.generic import ListView, CreateView
from django.urls import reverse_lazy
from django.shortcuts import redirect
from .models import Post, Tag
class ListClass(ListView):
template_name = 'list.html'
model = Post
class FormClass(CreateView):
template_name = 'form.html'
model = Post
fields = ('title', 'text')
success_url = reverse_lazy('list')
def form_valid(self, form):
post = Post(
title=form.cleaned_data["title"], text=form.cleaned_data["text"])
post.save()
words = form.cleaned_data["text"].split()
for word in words:
if word[0] == "#":
if Tag.objects.filter(name=word[1:]).exists():
tag = Tag.objects.get(name=word[1:])
else:
tag = Tag.objects.create(name=word[1:])
post.tag.add(tag)
return redirect('list')
splitの中を指定しないことで空白、改行などで分割ができる
分割して受け取った単語ごとにforを回す。先頭文字が「#」ならタグとみなす。
「#」以降の文字のタグが存在するかしないかで、新たにタグを作るか分岐する。
post.tag.add(tag)
でPostクラスのtagに追加する。
####出力結果
#####次のような投稿をしてみる
注)前の投稿内容は一度削除しました
###3.タグの検索機能作ってみる
mysite/post/views.py
class ListClass(ListView):
template_name = 'list.html'
model = Post
def get_queryset(self):
tag = self.request.GET.get('tag')
if tag:
post_list = Post.objects.filter(
tag__name__icontains=tag)
else:
post_list = Post.objects.all()
return post_list
ListClassを少し編集する
filterで注意ないといけなかったのが
Post.objects.filter(tag__name__icontains=tag)
PostのtagはManyToManyField(Tag)
なのでTagクラスのnameで検索を絞り込まなくてはいけなかった。
検索については以前に記事にしたので、気になった方はぜひ
簡単な検索機能を作ってみた
mysite/templates/list.html
<div class="container">
<form action="" method="get">
<input name="tag" value="{{ request.GET.tag }}" type="text" />
<button type="submit">検索する</button>
</form>
{% for post in object_list %}
<div class="post">
<p>タイトル<br />{{ post.title }}</p>
<p>内容<br />{{ post.text|linebreaksbr }}</p>
<p>--------------------</p>
</div>
{% endfor %}
<div class="form">
<a href="{% url 'form' %}">新規投稿</a>
</div>
</div>
tagという変数に検索ワードを入れる
「2回目」と検索してみる
検索出来てしっかり絞り込めています
###最後に
今回は#タグでタグ付けの機能を作りました。検索で投稿を絞るところまで作ってみました。
ここから、タグごとにaタグなどで絞り込んだりしてみても面白いなと思います。
今回作ったもののgithub