実行環境
実行環境は以下の通りです。
Python3 -- Python 3.9.0
Django -- 3.1.3
DjangoでのManyToManyFieldのオブジェクト操作について
今回、Djangoでwebアプリを作成していく内にハマったオブジェクト操作についてメモがてらに記述しておきます。
また、Djangoの学習を始めたばかりで非効率的なコードばかりですが、何かあればご指摘いただければ幸いです。
シチュエーション
ユーザー(User)とスケジュール(Schedule)をManyToManyFieldで紐付けるような構成のモデルを作成しました。「マイページにその人のスケジュールのみを表示させる」という実装を行いました。
ちなみに、Userはデフォルトのユーザモデルを使用しており、Scheduleのモデルを以下に示します。
models.py
class Schedule(models.Model):
"""スケジュール"""
summary = models.CharField('概要', max_length=50, help_text="○年○月")
description = models.TextField('詳細な説明', blank=True)
date = models.DateField('日付')
members = models.ManyToManyField(User, blank=True)
このScheduleのmembersにログイン中のユーザが含まれているもののみ表示させる、ということを実装したくて、以下のようなオブジェクト操作をしましたが、エラーが出てしばらくハマってしまいました。
views.py
def mypage(request):
login_user_id = request.user.id
who = User.objects.filter(id=login_user_id)
data = Schedule.objects.filter(members=who)
params = {'id':login_user_id,'who':who,'data':data}
return render(request, 'YukaSite/mypage.html',params)
エラーメッセージは以下です。
The QuerySet value for an exact lookup must be limited to one result using slicing.
要するにフィルターの条件がリストになっていなかったため、エラーが出ているとのことでした。
○○__in=リスト
の形にすることで、「ある値がリストに含まれているか」で検索を行えます。
よって上記のview.pyのdataのフィルター操作(4行目)を以下のように変え、解決しました。
data = Schedule.objects.filter(members__in=who)
そもそもデフォルトのユーザ操作もよくわかっておらず無駄な記述が多いと思いますが、
何かあればご指摘いただけると幸いです。