LoginSignup
0
1

More than 1 year has passed since last update.

Django タグ付け機能

Posted at

Twetterなどで使われているタグ付け機能を作ってみようと思い作成してみました。
とりあえず機能として成り立てばいいかなと思い作成したので、改善点などがあればコメント等で教えていただけたら嬉しいです。

タグ付け機能をつけるモデル

models.py
class Tag(models.Model):
    name = models.CharField(max_length=50, unique=True)

class Notes(models.Model):
    title = models.CharField(max_length=255)
    content = models.CharField(max_length=500)
    tags = models.ManyToManyField(Tag)
    favorites = models.ManyToManyField(Users, blank=True, related_name='favorite_notes')
    user = models.ForeignKey('accounts.Users', on_delete=models.CASCADE)

タグ付け機能を行うモデルとして、「Tag」と「Notes」を定義しました。
「Tag」モデルはタグを保存するためのモデルになっており、「Notes」モデルのtagsフィールドで多対多で紐付いています。
アプリの機能としてはノートをタグにより分類する感じになります。

フォームの作成

forms.py
class CreateNoteForm(forms.ModelForm):
    title = forms.CharField(label='タイトル')
    tags = forms.CharField(label='タグ') # タグを入力するためのフィールド
    content = forms.CharField(label='あらすじ', widget=forms.Textarea())

    class Meta:
        model = Notes
        fields = ('title', 'content') # Notesモデルにタグ自体を保存しないので除く

フォームにタグ入力するためのフィールドを作成するためにtagsを定義してますが、Notesモデルには保存しないのでfieldstagは指定しません。

ビューの作成

ビューの関数内でタグの保存の処理などを行います。

views.py
def create_note(request):
    create_note_form = forms.CreateNoteForm(request.POST or None)
    if create_note_form.is_valid():
        note = create_note_form.save(commit=False) # save(commit=False)で保存せずにインスタンスを受け取る
        note.user = request.user # Notesはユーザーモデルとも紐付いているのでユーザーを指定
        note.save() # タグ以外のフィールドを保存
        tags = create_note_form.cleaned_data['tags'] # tagsフィールドに入力された値を取得
        tag_list = tags.split() # 入力された値をsplitで半角スペースごとに区切る
        for tag in tag_list:
            tag = tag.lower() # 区切られた値をlowerで小文字にする
            if Tag.objects.filter(name=tag).exists(): # existでタグが既にあるか判定(ある:True,ない:False)
                add_tag = Tag.objects.filter(name=tag).first() # 存在する場合はタグを取得
                note.tags.add(add_tag) # addでタグを追加
            else:
                add_tag = Tag.objects.create(name=tag) # 存在しない場合タグを新しく作成
                note.tags.add(add_tag)
        
    return render(request, 'note/create_note.html', context={
        'create_note_form': create_note_form,
    })

note.save()でタグ以外のフィールドを先に保存し、その後にタグを紐付けていきます。
cleaned_data['tags']でtagsフィールドに入力された値を取得し、tagsに代入しています。
タグは半角スペースで区切って入力するので、tagsで受け取った値をsplitで半角スペースごとに区切りtag_listにリスト型で代入。
for文でタグを一つずつ取得し、lowerで小文字に変換しています。同じ文字列でも別のデータとして扱われてしまうので今回は小文字に統一させます。(Python,python, PYTHONなどが別々に保存され統一性がなくなる)
if Tag.objects.filter(name=tag).exists():でタグが既に存在するか判定します。同じ文字列が複数ある場合でも統一性がなくなってしまいます。
タグが存在する場合、add_tag = Tag.objects.filter(name=tag).first()でタグを取得。
タグが存在しない場合、add_tag = Tag.objects.create(name=tag)でタグを新規作成。
note.tags.add(add_tag)により関連付ける事ができる。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1