4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Django】登録・編集フォーム(Form)でユーザーに紐づく登録データを表示する

Last updated at Posted at 2020-04-11

やりたいこと

Modelに外部キー(FOREIGN KEY)制約のある2つのテーブルを用意したとき、Formではユーザー(ログインユーザー)に紐づいた、登録データを表示したいです。
クラスベースの汎用ビューを使ったときの、やり方でつまずいたので、記録しておきます。

例えば、以下のようなTodoリストを作成します。
このとき、1つのTodo Itemには選択できるCategoryが複数あります。
todo_2.png

以下のように、ログインユーザーで登録しているCategoryが2つあるとします。
todo_3-crop.png

このとき(当然のことですが)、登録や編集のフォームで選択できるCategoryは、ログインユーザーが登録したCategoryのみとしたいです。

todo_1.png

環境

Python 3.8.0
Django 3.0.4
Bootstrap 4.1.3
プラグイン:django-bootstrap-modal-forms
※一般的なCreateView、UpdateView等を使う場合も同様のやり方です

やり方

このページを参考にしました。

使用するModel


# mypeoject/myapp/models.py
import datetime
from django.db import models


class Category(models.Model):
    category_name = models.CharField(max_length=20, unique=True)
    user = models.ForeignKey(
        'auth.User',
        on_delete=models.CASCADE
    )

    def __str__(self):
        return self.category_name


class TodoItem(models.Model):
    item = models.CharField(max_length=50)
    item_date = models.DateField(default=datetime.date.today)
    categories = models.ForeignKey(Category, null=True, on_delete=models.SET_NULL)
    user = models.ForeignKey(
        'auth.User',
        on_delete=models.CASCADE
    )

    def __str__(self):
        return self.item

上記の例の場合、使用するModelには、TodoItemテーブルと、外部キー(FOREIGN KEY)制約のあるCategoryテーブルの2つを用意しています。

forms.pyの編集


# mypeoject/myapp/forms.py
from bootstrap_modal_forms.forms import BSModalForm
from django import forms

from queryset_filtering_app.models import TodoItem, Category


class CreateUpdateTodoItemForm(BSModalForm):
    class Meta:
        model = TodoItem
        fields = ['item', 'item_date', 'categories']

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user')
        super(CreateUpdateTodoItemForm, self).__init__(*args, **kwargs)
        self.fields['categories'].queryset = Category.objects.filter(user=user)


class CreateCategoryForm(forms.ModelForm):
    class Meta:
        model = Category
        fields = ["category_name"]

forms.pyは上記のように、def __init__()の記述を追加します。

views.pyの編集


# mypeoject/myapp/views.py
class CreateTodoItemFormView(BSModalCreateView):
    template_name = 'template_name.html'
    form_class = CreateUpdateTodoItemForm
    success_message = 'Success: Item was created.'
    success_url = reverse_lazy('redirect_name')

    def get_form_kwargs(self):
        kwargs = super(CreateTodoItemFormView, self).get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

    def form_valid(self, form):
        form.instance.user_id = self.request.user.id
        return super(CreateTodoItemFormView, self).form_valid(form)


class UpdateTodoItemFormView(BSModalUpdateView):
    model = TodoItem
    template_name = 'template_name.html'
    form_class = CreateUpdateTodoItemForm
    success_message = 'Success: Item was updated.'
    success_url = reverse_lazy('redirect_name')

    def get_form_kwargs(self):
        kwargs = super(UpdateTodoItemFormView, self).get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

views.pyでは上記のように、def get_form_kwargs()の記述を追加します。
CreateViewのdef form_valid()の箇所は、登録時にログインユーザーをuserに登録するためのコードです。

おわりに

登録・編集フォームでユーザーに紐づく登録データを表示する方法を記載しました。
基本的なところだと思いますが、私のような初心者だと、適切な記事を見つけられず、すぐには解決できないこともあるかと思うので、参考にしていただければと思います。

4
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
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?