質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.35%
Django

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

2061閲覧

Django ユーザー名の値をフォーム入力時に一緒に持たせる方法。

Mamiya_tom

総合スコア17

Django

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2020/04/26 02:32

編集2020/04/27 02:21

現在、各ユーザーが投稿できる簡易のSNSを作ろうとしているのですが、投稿者名の表示方法がわかりません。
下記コードの場合だとログイン中のユーザーが変わるたびに投稿者名も変わってしまいます。

html

1<div class="col-4"> 2 <p>User:<a href="{% url 'register:user_detail' user.pk %}">{{ user.first_name }}</a></p> 3</div>

どこかのタイミングで投稿者名の値を渡さなければいけないと思うのですが、どのタイミングでどのように書くのかわかりません。
ざっくりでもいいので流れなどアドバイスいただきたいです。
わかりやすいサイトなども教えていただけると幸いです。
よろしくお願いいたします。

views.py

python

1#詳細画面 2class ItemDetailView(DetailView): 3 model = Item 4#投稿画面 5class ItemCreateView(LoginRequiredMixin, CreateView): 6 model = Item 7 form_class = PostForm 8 template_name = 'register/item_form.html' 9 success_url = reverse_lazy('register:top') 10 11# 更新画面 12class ItemUpdateView(LoginRequiredMixin, UpdateView): 13 model = Item 14 form_class = PostForm 15 success_url = reverse_lazy('register:top') 16 17# 削除画面 18class ItemDeleteView(LoginRequiredMixin, DeleteView): 19 model = Item 20 success_url = reverse_lazy('register:top')

forms.py

python

1class PostForm(forms.ModelForm): 2 class Meta: 3 model = Item 4 fields = ('title', 'content','category',) 5 widgets = { 6 'title': forms.TextInput(attrs={'placeholder':'タイトルを入力してください'}), 7 }

urls.py

python

1 path('user_detail/<int:pk>/', views.UserDetail.as_view(), name='user_detail'),#int:pkは登録の番号(プライマリーキー) 2

参考サイト
https://qiita.com/okoppe8/items/54eb105c9c94c0960f14
https://narito.ninja/blog/detail/38/

追記

詳細画面のHTMLを追記させていただきます。

html

1{% load markdown_extras %} 2<div class="row"> 3 <div class="col-4"> 4 <a href="{% url 'register:user_detail' user.pk %}"><p>{{ user.first_name }}</p></a> 5 </div> 6 <div class="col-4"> 7 <p>{{ item.category }}</p> 8 </div> 9 <div class="col-4"> 10 <p>{{ item.created_at|date:"Y/m/d" }}</p> 11 </div> 12</div> 13<div class="row"> 14 <div class="card-text pl-0 pr-0" id="content"> 15 {{ item.content|markdown|safe }} 16 </div> 17</div>

#追記
models.pyを追記させていただきます。

python

1class Item(models.Model): 2 CATEGORY = [ 3 ("ビジネス","ビジネス"), 4 ("お金","お金"), 5 ("スポーツ","スポーツ"), 6 ("ライフスタイル","ライフスタイル"), 7 ("暇つぶし","暇つぶし"), 8 ("あるある","あるある"), 9 ("芸能","芸能"), 10 ("おもしろ","おもしろ"), 11 ("趣味","趣味"), 12 ("その他","その他"), 13 ] 14 15 title = models.CharField(verbose_name='タイトル',max_length=200,) 16 content = MDTextField() 17 category = models.CharField(verbose_name='カテゴリー',max_length=150,blank=True,choices=CATEGORY,) 18 created_at = models.DateTimeField(verbose_name='登録日',auto_now_add=True) 19 tags = TaggableManager(blank=True) # 追加 20 21 class Meta: 22 verbose_name = 'アイテム' 23 verbose_name_plural = 'アイテム' 24

よろしくお願いいたします。

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

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

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

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

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

llr114

2020/04/26 17:08

可能でしたら、view内での対応する画面名(詳細画面なのか投稿画面なのか、など)と該当するHTML文の全文をいただけないでしょうか?
Mamiya_tom

2020/04/27 01:20

ありがとうございます。 詳細画面で対応させたいと思っています。HTMLも追記させていただきました。
llr114

2020/04/27 01:48

ごめんなさい、一点お願いし忘れてました。 models.pyの追記もお願いしてもよよろしいでしょうか? Itemの中身がみたいです。
Mamiya_tom

2020/04/27 02:21

返信ありがとうございます。 modelの追記させていただきました。 よろしくお願いいたします。
llr114

2020/04/27 02:23

ありがとうございます。 Itemに投稿者名が見当たらないのですが、User側から紐づけてるということでしょうか?
Mamiya_tom

2020/04/27 02:38

そこから理解できているか怪しいです。 今は消去しましたが、'foreignkey'で紐付けしたのですがうまくいかなかったので、質問し現在に至る感じです。
guest

回答1

0

ベストアンサー

私だったらどうするかどう考えるかを書きます。

要するにテンプレートで以下のようなことがしたいのではないのでしょうか?

html

1{{ item. title}} #記事のタイトルを表示 2 3{{ 記事作成者 }} #この記事作成者を表示 最終的には{{ item.post_user }}で表示させます 4 5{{ item.category }} #記事カテゴリを表示 6 7{{ item.created_at|date:"Y/m/d" }} #記事作成日を表示 8 9{{ item.content|markdown|safe }} #記事内容を表示 10 11 12

このようなことを実現したい場合には、Itemのインスタンス(Item.objects.create()した結果)にUserインスタンスを含めることが必要になります。
つまり、

python

1views.pyにて 2 3#投稿者のUserインスタンスを取得 4user_obj = User.objects.get(username=request.user.name) 5#投稿者のUserインスタンスを使ってItemインスタンスを生成する 6item_obj = Item.objects.create(category="あるある",title="わわわ", content="いいい", post_user=user_obj )

こういう事ができれば、テンプレートで{{ item.post_user }}を実行すれば投稿者を表示することができます。

しかしながら、質問者様のItemモデルには、post_userがありませんよね?
だから、

python

1item_obj = Item.objects.create(category="あるある",title="わわわ", content="いいい", post_user=user_obj )

を実行すると、そんなフィールドはありませんとエラーが出てしまいます。

そこでItemモデルにpost_userを追加するのです。

python

1 2class Item(models.Model): 3 CATEGORY = [ 4 ("ビジネス","ビジネス"), 5 ("お金","お金"), 6 ("スポーツ","スポーツ"), 7 ("ライフスタイル","ライフスタイル"), 8 ("暇つぶし","暇つぶし"), 9 ("あるある","あるある"), 10 ("芸能","芸能"), 11 ("おもしろ","おもしろ"), 12 ("趣味","趣味"), 13 ("その他","その他"), 14 ] 15 16 title = models.CharField(verbose_name='タイトル',max_length=200,) 17 content = MDTextField() 18 category = models.CharField(verbose_name='カテゴリー',max_length=150,blank=True,choices=CATEGORY,) 19 created_at = models.DateTimeField(verbose_name='登録日',auto_now_add=True) 20 tags = TaggableManager(blank=True) # 追加 21 post_user = models.ForeignKey(User, on_delete=models.PROTECT) #コレ 22

すると、Itemのインスタンスを生成することが成功できますし、ひいてはテンプレートに投稿者データを表示することができます。

*私もForeignKeyやManyToManyとか苦手意識がありましたが、これらのフィールドには他のModelインスタンスを格納するフィールドとイメージしておけば、使えるようになりますよ。フィールドに格納するインスタンスの個数によってForeignKey, ManyToManyとか使い分けるようにしてみてください。

*最近djangoを触っていないので細かいところでエラーが出てしまう恐れがありますが、この考え方は間違いないと思われます。

追記:

質問者様が使われているのはClassBasedViewの中のCreateViewを使っていることを失念していました。こちらについての私なりの考えを述べ、サンプルコードを書いてみます。

CreateViewを始めListView, DetailView, UpdateView等はすべてViewを継承して作られたものです。これらは、どのようなロジックで動くか予め設定してあります。だから素早く開発したい場合には便利ですが、ロジックに外れた複雑なことをしようとする場合には自分で色々CreateViewのロジックを書き換えなければなりません。
一方、Viewはロジックをすべて自分で書かなければいけませんが自由度が高いです。基本的にこちらでwebアプリを作る方が凝った物が作れると思われます。

まだCreateViewの構造を把握されていないと思われるのでCreateViewの各メソッドをオーバーライドするよりも、Viewクラスを利用して書く方法を提示します。

python

1from ***.*** import PostForm 2from django.views.generic import View 3 4class ItemCreateView(View): 5 #ユーザーがGETを実行したら以下のメソッドが実行される 6 #ユーザーに入力フォームを表示する役割です 7 def get(self, request, *args, **kwargs): 8 context = {} 9 if request.user.is_anonymous: 10 return HttpResponse("ログインしてください") 11 #ユーザーにどのような入力フォームを表示させるかを準備する 12 form = PostForm() 13 context["form"] = form 14 return render(request, 'register/item_form.html', context) 15 16 #ユーザーがPOSTを実行したら以下のメソッドが実行される 17 #ユーザーの入力したデータに基づいてItemインスタンスを生成する役割です。 18 def post(self, request, *args, **kwargs): 19 context = {} 20 if request.user.is_anonymous: 21 return HttpResponse("ログインしてください") 22 #ユーザーの入力データの受取 23 form = PostForm(request.POST) 24 #入力内容のチェック 25 if form.is_valid(): 26 item_obj = form.save(commit=False) 27 #ココでUserオブジェクトを追加。 28 item_obj.post_user = User.objects.get(username=request.user.name) 29 item_obj.save() 30 return redirect('register:top') 31 return redirect('ItemCreateViewの逆引き用のname')

ちなみにcreateメソッドでアドバイスしましたのでcreateメソッドを使う方法も記述しておきます。

python

1 2if form.is_valid(): 3 title = form.cleaned_data['title'] 4 content = form.cleaned_data['content'] 5 category = form.cleaned_data['category'] 6 user_obj = User.objects.get(username = request.user.name) 7 Item.objects.create(title=title, content=content, category=category, post_user=user_obj) 8 return redirect('register:top') 9 10...

どう開発されているかわかりませんが、基本的にViewクラスを継承したものを作って開発するほうが最終的に何でも対応できてしまうと思います。わたしはめったにView以外のclassBasedViewを使いません。

もしViewの使い方がわからなければViewから学習を進めると遠回りのようで近道だと思います。

もしViewの使い方を勉強しても難しいようであれば、関数型Viewの知識が足りないかもしれません。
クラスベースのViewは関数型ViewのGET,POST等のTHHPメソッドによる分岐をクラスメソッドとしてget, post等に切り分けただけなので、以下のようなサイトの関数型ビューの使い方に慣れて、関数型ビューが煩雑だなと思った時にクラス型のViewに乗り換えればいいと思います。

https://djangobrothers.com/tutorials/blog_app/top_page/

投稿2020/04/27 19:05

編集2020/04/28 07:04
chapin

総合スコア80

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

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

Mamiya_tom

2020/04/28 04:29

わかりやすいご説明をありがとうございます! `post_user = models.ForeignKey(User, on_delete=models.PROTECT)`をmodelsに追加したのですが、投稿画面の`success_url `で遷移できませんでした。この場合、views.pyの書く場所がおかしかったのでしょうか? ちなみに、`ItemCreateView`の中に、 def user_name(request): #投稿者のUserインスタンスを取得 user_obj = User.objects.get(username=request.user.first_name) #投稿者のUserインスタンスを使ってItemインスタンスを生成する item_obj = Item.objects.create(post_user=user_obj ) return item_obj と入れました。 理解力が乏しく申し訳ありません。 お手隙の際に何かアドバイスいただけたら幸いです。
Mamiya_tom

2020/04/28 10:28

丁寧に解説してくださりありがとうございます。 改めて自分の知識の足りなさを痛感いたしました。 サイトを見ながら学んでいきたいと思います。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問