🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

1522閲覧

DjangoのModelFormで、特定の選択肢のみを表示する方法

Hajimeru

総合スコア0

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/03/06 10:13

編集2021/03/10 12:08

実現したいこと

Djangoで簡易的なSNSを作成しています。
Groupを作成し、そこにメンバーを追加できるようにしていきたいのですが、Form上では既に繋がったFriendsだけを選択できるようにしたいです。
現状は繋がっていない全てのユーザーが表示されてしまいます。

構成としてはGroup, GroupMember, Profile, FriendRequestというモデルがあります。
GroupでGroup作成、GroupMemberではすでに作成されたGroupに対してメンバーを追加するというものです。
ProfileモデルはOnetoOneFieldでCustomUserモデルに紐づいていて、そのProfileモデルの中にFriendsという項目があります。

このような構成で、どのようにquerysetを書けば、既に繋がったFriendだけをGroupMemberの選択肢として絞ることが出来るのかがわかりません。
すみませんが、ご教授いただけますでしょうか。

プログラミングの素人がやっているので分かりづらい表現があるかもしれません。
もし足りない点がありましたら、ご指摘頂ければ幸いです。

該当のソースコード

models.py

1 2class Group(models.Model): 3 owner = models.ForeignKey(CustomUser, on_delete=models.CASCADE, \ 4 related_name='group_owner') 5 6 title = models.CharField(max_length=100) 7 8 def __str__(self): 9 return self.title 10 11 12class GroupMember(models.Model): 13 group = models.ForeignKey(Group, on_delete=models.CASCADE) 14 member = models.ForeignKey(CustomUser, on_delete=models.CASCADE, blank=True, null=True) 15 16 class Meta: 17 verbose_name_plural = 'Group Member' 18 19 def __str__(self): 20 return str(self.member) + ' (group:"' + str(self.group) + '")' 21 22 23class Profile(models.Model): 24 user = models.OneToOneField(CustomUser, verbose_name='User', on_delete=models.CASCADE) 25 name = models.CharField(verbose_name='name', max_length=40, blank=True, null=True) 26 image = models.ImageField(default='default.png', upload_to='profile_pics') 27 slug = AutoSlugField(populate_from='user') 28 friends = models.ManyToManyField("Profile", blank=True) 29 30 class Meta: 31 verbose_name_plural = 'Profile' 32 33 def __str__(self): 34 return str(self.user.username) 35 36 def get_absolute_url(self): 37 return "/process/{}".format(self.slug) 38 39class FriendRequest(models.Model): 40 to_user = models.ForeignKey(CustomUser, related_name='to_user', on_delete=models.CASCADE) 41 from_user = models.ForeignKey(CustomUser, related_name='from_user', on_delete=models.CASCADE) 42 timestamp = models.DateTimeField(auto_now_add=True) 43 44 def __str__(self): 45 return "From {}, to {}".format(self.from_user.username, self.to_user.username 46 47

forms.py

1 2class GroupCreateForm(forms.ModelForm): 3 class Meta: 4 model = Group 5 fields = ['title'] 6 7 8class MemberCreateForm(forms.ModelForm): 9 class Meta: 10 model = GroupMember 11 fields = ['group', 'member'] 12 13 def __init__(self, *args, **kwargs): 14 user = kwargs.pop('place_member') 15 super().__init__(*args, **kwargs) 16 self.fields['group'].queryset = Group.objects.filter(Q(owner=user)|Q(groupmember__member=user)) 17 self.fields['member'].queryset = CustomUser.objects.all() 18 19 for field in self.fields.values(): 20 field.widget.attrs['class'] = 'form-control' 21

viewss.py

1#GroupMember作成 2class MemberCreateView(LoginRequiredMixin, generic.CreateView): 3 model = GroupMember 4 template_name = 'group_add_friend.html' 5 form_class = MemberCreateForm 6 success_url = reverse_lazy('process:sop_list') 7 8 def get_form_kwargs(self): 9 kwargs = super(MemberCreateView, self).get_form_kwargs() 10 kwargs.update({'place_member': self.request.user}) 11 return kwargs 12 13 def form_valid(self, form): 14 group = form.save(commit=False) 15 group.owner = self.request.user 16 group.save() 17 messages.success(self.request, 'Group Memberを作成しました。') 18 return super().form_valid(form) 19 20 def form_invalid(self, form): 21 messages.error(self.request, "Group Memberの作成に失敗しました。") 22 return super().form_invalid(form) 23 24

試したこと

MemberCreateFormのquerysetをいじってみたのですが、皆目見当がつきません。
groupの選定では直接querysetを作り、ここはうまくいっています。
ただ、自分とFriendとして繋がっているようなCustomUserのみをここで表示する方法が分かりません。

self.fields['member'].queryset = CustomUser.objects.all()

上記のコードではCustomUser.objects.all()となっていますが、最終形がどうなるか分からず、現状このようにしています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

FormView派生クラスのビューを使用しているのであれば、下記でどうでしょうか。

python

1class FooView(CreateView): 2 def get_form(self, form_class=None) -> forms.Form: 3 form = super().get_form(form_class) 4 form.fields['member'].queryset = CustomUser.objects.filter(...) 5 ... 6 return form

投稿2021/03/09 05:25

hasami

総合スコア1277

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Hajimeru

2021/03/09 18:48

有難うございます。まことに恐縮ではありますが、追加で質問させて頂けますでしょうか。 上記のmemberを選択する部分で、Profileモデルのfriendsになっている人間のみ表示したいです。 Profileモデルのfriendsはシンメトリーな関係になっています。このような関係になっている中でどのようにfilterすれば自分とfriendsになっている人のみを表示出来るのかが分かりません。 下記の(...)の部分をどのように記載すれば良いか、ご教授頂けますでしょうか。 CustomUser.objects.filter(...)
hasami

2021/03/09 23:46

どのようにビューを実装しているのでしょうか。 質問に追記してください。
Hajimeru

2021/03/10 12:12

有難うございます。現状のビューを追記致しました。 ご確認のほど、よろしくお願い致します。 ユーザー全員を出すことは出来ているので、modelFormのquerysetの記載の仕方でfriendsだけを出すことが出来るのではと考えたのですが、うまく出来ません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問