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

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

詳細はこちら
Django

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

Python

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

Q&A

解決済

2回答

1163閲覧

index.htmlからas_hiddenを使用し、viewsにpkを渡したいのだがprint(form.cleaned_data.get('pk'))がNoneになる

jqk

総合スコア26

Django

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

Python

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

0グッド

0クリップ

投稿2021/03/07 10:19

編集2021/03/09 04:32

現在チャットアプリの為にRoomモデルを作成したいのですが上手くviewpkを渡せていないみたいです。
TeacherモデルとCustomerモデルがありまして、
それぞれのモデルとRoomモデルを紐づけてあります。

[accounts/models.py]

from django.contrib.auth.models import AbstractUser from django.db import models class User(AbstractUser): is_customer = models.BooleanField(default=False) is_teacher = models.BooleanField(default=False) class Customer(models.Model): user = models.OneToOneField(User, on_delete = models.CASCADE, primary_key = True) age = models.CharField(verbose_name='年齢', blank=True, null=True, max_length=10) personality = models.TextField(verbose_name='アピールポイント', blank=True, null=True, max_length=1000) profile_picture = models.ImageField(verbose_name = 'プロフィール画像', blank=True, null=True, upload_to='images/', default='default_user_icon.png') def __str__(self): return self.user.username class Teacher(models.Model): user = models.OneToOneField(User, on_delete = models.CASCADE, primary_key = True) age = models.CharField(verbose_name='年齢', blank=True, null=True, max_length=10) personality = models.TextField(verbose_name='アピールポイント', blank=True, null=True, max_length=1000) profile_picture = models.ImageField(verbose_name = 'プロフィール画像', blank=True, null=True, upload_to='images/', default='default_user_icon.png') def __str__(self): return self.user.username

[models.py]

from django.db import models from django.conf import settings from accounts.models import User, Customer, Teacher class Room(models.Model): teacher_id = models.ForeignKey(Teacher, null=True, blank=True, on_delete=models.CASCADE) customer_id = models.ForeignKey(Customer, null=True, blank=True, on_delete=models.CASCADE)

ログイン中のカスタマーが選択したteacherに連絡する為の連絡するボタンをクリックすると、
POSTが実行されます。
{{ form.object.teacher.pk.as_hidden }}を使用し、
for文によって回されたteacherのpkを記述しています。

[index.html]

{% if user.is_authenticated %} <div class="row row-cols-1 row-cols-md-3 g-4"> {% for object in object_list %} <div class="user_col"> <div class="col"> <form action="{% url 'create_room' %}" method="POST"> {% csrf_token %} {{ form.object.teacher.pk.as_hidden }} <div class="card h-100"> <img src="{{ object.teacher.profile_picture.url }}" class="card-img-top" height="280"> <div class="card-body"> <h5 class="card-title name_age">{{ object.username }}</h5><h5 class="card-title name_age">( {{ object.teacher.age }} 歳)</h5> <p class="card-text">{{ object.teacher.personality }}</p> {% if user.customer %} <button class="btn btn-primary" class="submit">連絡する</button> {% endif %} </div> </div> </form> </div> </div> {% endfor %} </div> {% else %}

そしてここで、テンプレートから渡されたteacherのpkとログイン中のcustomerのpkを使用しfilterにかけたいのですが、print(form.cleaned_data.get('pk')を試すと出力結果がNoneになります。
{{ form.object.teacher.pk.as_hidden }}おそらくこちらの記述方法が間違ってると思ってます。
ご教授頂ければ幸いです。よろしくお願い致します。

[views.py]

from django.shortcuts import redirect from django.views.generic import ListView, DetailView from .forms import CreateRoomForm from accounts.models import User from .models import Room, Message class TeacherListView(ListView): model = User template_name = 'index.html' def get_queryset(self): queryset = User.objects.filter(is_teacher=True) return queryset class RoomMessagesListView(DetailView): model = Message template_name = 'room.html' def CreateRoom(request): if request.method == 'POST': form = CreateRoomForm(request.POST) if form.is_valid(): room_data = Room.objects.filter(teacher_id=form.cleaned_data.get('pk'), customer_id=request.user.pk) if room_data is not None: return redirect('room', pk=room_data[0].pk) else: room_data = Room() room_data.teacher_id = form.cleaned_data.get('pk') room_data.customer_id = request.user.pk room_data.save() return redirect('room', pk=room_data.pk)

[forms.py]

from django import forms from .models import Room class CreateRoomForm(forms.ModelForm): class Meta: model = Room fields = ('teacher_id',)

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

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

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

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

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

guest

回答2

0

自己解決

<index.html>
{{ form.object.teacher.pk.as_hidden }}
↓変更
<input type="hidden" name="pk" value="{{ object.teacher.pk }}">

<views.py>
以下のコードで取得できます。
request.POST["pk"]

投稿2021/03/11 00:40

jqk

総合スコア26

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

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

0

下記のようにしたらどうなりますか。

html

1<!-- index.html --> 2{{ form.teacher_id.as_hidden }}

python

1# views.py 2def CreateRoom(request): 3 if request.method == 'POST': 4 form = CreateRoomForm(request.POST) 5 if form.is_valid(): 6 # room_data = Room.objects.filter(teacher_id=form.cleaned_data.get('pk'), customer_id=request.user.pk) 7 room_data = Room.objects.filter( 8 teacher_id=form.cleaned_data.get('teacher_id'), 9 customer_id=request.user.pk)

投稿2021/03/08 09:42

編集2021/03/09 04:16
hasami

総合スコア1277

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

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

jqk

2021/03/08 11:04 編集

ご教授ありがとうございます! エラー変わらずです。 おそらくform.cleaned_data['pk']の記述方法が間違っていたので上記エラー出てました。 form.cleaned_data.get('pk') こちらに変更すると上記のエラーはなくなりました。 ですがprint(form.cleaned_data.get('pk'))を使用しログを確かめるとNoneになっていましたので、 おそらくindex.htmlのformの渡し方が間違っているのでは?と思っております。 因みにprint(request.user.pk)は思ってる通りの値が取得出来ています。 またviewを少し変更しましたので、よろしければ再度ご教授頂ければ幸いです。
jqk

2021/03/09 04:33 編集

@hasami 提供頂きました追加のコード試した結果、下記コード部分でlist index out of rangeというエラーが表示されてしまいます。 return redirect('room', pk=room_data[0].pk) print(form.cleaned_data.get('teacher_id'))を試しましたが、Noneと出力されてしまいました。 何度もありがとうございます。 viewの記載情報が不足してるかもしれませんので、 念のためコード追加しました。
hasami

2021/03/09 05:11

filterメソッドで条件に一致するモデルインスタンスが存在しない場合、空のQuerySetが返却されます。 よって、rood_data[0]が評価されて、IndexErrorがスローされていると想像します。 また、フォームでteacher_idを設定しているコードが見当たらないため、form.cleaned_data.get('teacher_id')がNoneを返却されていると想像します。 CreateRoomビュー関数で、リクエストメソッドがGETの場合に、フォームのhiddenであるteacher_idを設定する必要があるのではないですか。
jqk

2021/03/09 11:03 編集

何度もご教授ありがとうございます! >CreateRoomビュー関数で、リクエストメソッドがGETの場合に、フォームのhiddenであるteacher_idを設定する必要があるのではないですか。 ということは以下のように変更するという解釈で合っていますでしょうか? CreateRoomForm(request.POST) ⇨ CreateRoomForm(request.GET) {{ form.object.teacher.pk.as_hidden }} ⇨ {{ form.teacher_id.as_hidden }} 因みにもしテンプレートの方でmethod="POST"を使用したければ以下コードのように、 viewの方でもif request.method == 'POST':を使用しなければいけないという解釈で合っていますでしょうか? <form action="{% url 'create_room' %}" method="POST"> if request.method == 'POST':
jqk

2021/03/09 11:12

いえ、単純に上記の変更をしてもダメですよね? もしGETの時にRoomモデルを作成したいなら、 TeacherListViewにRoomモデルを作成するコードを追加する必要がありそうですよね?
hasami

2021/03/10 00:03

下記のような感じでしょうか。 POSTの場合は入力されたデータでフォームを作成して、GETの場合はinitialでフォームを作成します。 initial = {'teacher_id': 1} form = CreateRoomForm(request.POST or None, initial=initial)
jqk

2021/03/11 00:41

hasamiさん何度も助けて頂きありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問