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

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

詳細はこちら
Django

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

URL

URL(ユニフォームリソースロケータ)とは、インターネット上のリソース(Webページや電子メールの宛先等)を特定するための形式的な記号の並びの事を言う。

Python

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

Q&A

解決済

1回答

2247閲覧

Django Viewから複数idを取得する方法を知りたい。

koyakoya

総合スコア6

Django

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

URL

URL(ユニフォームリソースロケータ)とは、インターネット上のリソース(Webページや電子メールの宛先等)を特定するための形式的な記号の並びの事を言う。

Python

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

0グッド

0クリップ

投稿2019/10/21 07:55

編集2019/10/22 08:08

【Python Django】urlに複数idを使う際にViewからidを取得する方法を知りたい。

お世話になります。Django初心者です。
初歩的な質問が2点あります。
恐れ入りますが、ご教示いただけると幸いです。

###環境
Windows10
Django 2.2.6
Python 3.7.1

###アプリについて
作りたいアプリは、blogの様なレポートを登録するアプリで
ユーザー毎にレポートを登録していくものです。
レポートはジャンルを作成して、そのジャンル毎にレポートを追加して行く構成です。

以下のような画面遷移になります。
ユーザーログイン画面
↓  ①ユーザーログイン
top画面
↓  ②レポート一覧表示
レポートジャンル一覧画面
↓  ③一覧からジャンルを選ぶとレポートの一覧が表示
レポート一覧画面
↓  ④レポート一覧から選択する。 ⑤レポートの詳細を表示
レポート詳細画面

①ユーザーログイン(ユーザー登録はadminで登録し、別アプリのaccountsでloginします)
②ユーザーIDで紐づけた、レポートのジャンル情報(タイトルと内容)一覧を表示
③レポートのジャンル情報一覧画面から選択されたジャンルのレポート一覧を表示、または、新規ジャンル作成。
④選択したジャンルのレポート一覧を表示(ユーザーIDとジャンルIDで紐づいている)、または、新規レポート作成。
⑤レポートの詳細表示(ユーザーIDとジャンルIDとレポートIDで紐づく)

###質問1
上記の④のテンプレートに”レポート新規作成”ボタンを追加して
新規作成テンプレートへ遷移したいのですが、
④を行っているListViewの処理で、ジャンルIDを取得して、テンプレートに渡す方法がわかりません。
get_context_data内でジャンルIDをcontext['info_id']に渡せばよいと思うのですが方法が分からず悩んでいます。

###質問2
ユーザー登録が済んでいるが、レポートを何も登録していないときのviewの処理は、
以下のようなtryとexceptの処理で正しいでしょうか?

def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) try: report_list = Report.objects.get(id=self.kwargs.get['pk']) context['report_list'] = report_list return context except: return context

###コード

以下の構成のurls.pyでアプリを作成しています。
ユーザーID:int:pk
ジャンルID:int:info_id
レポートID:int:report_id

■urls.py

from django.urls import path from . import views app_name = 'reports' urlpatterns = [ path('', views.index.as_view(), name='index'), path('<int:pk>/reportInfo/', views.reportInfoListView.as_view(), name='top'), path('<int:pk>/reportInfo/create/', views.reportInfoCreateView.as_view(), name='reportInfoCreate'), path('<int:pk>/reportInfo/<int:info_id>/report/', views.reportListView.as_view(), name='reportList'), path('<int:pk>/reportInfo/<int:info_id>/report/create', views.reportCreateView.as_view(), name='reportCreate'), path('<int:pk>/reportInfo/<int:info_id>/report/<int:report_id>/', views.reportDetailView.as_view(), name='reportDetail'), ]

ユーザー認証は、別のaccountsアプリで行っており、レポートは、appアプリで行っています。
構成は、以下となります。

■view.py

from django.contrib.auth import get_user_model from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin from django.shortcuts import resolve_url from django.views import generic from .models import ReportInfo, Report from .forms import ReportInfoCreateForm, ReportCreateForm User = get_user_model() class OnlyYouMixin(UserPassesTestMixin): """本人か、スーパーユーザーだけユーザーページアクセスを許可する""" raise_exception = True def test_func(self): user = self.request.user return user.pk == self.kwargs['pk'] or user.is_superuser class index(LoginRequiredMixin, generic.TemplateView): template_name='reports/index.html' class reportInfoListView(OnlyYouMixin, LoginRequiredMixin, generic.ListView): """レポートジャンルの一覧。""" model=ReportInfo template_name='reports/reportInfoList.html' def get_queryset(self): current_user = self.request.user try: return ReportInfo.objects.filter(user=current_user.id) except: return queryset def get_context_data(self, **kwargs): current_user = self.request.user context = super().get_context_data(**kwargs) try: context['info_list']=ReportInfo.objects.filter(user=current_user.id) return context except: return context class reportInfoCreateView(OnlyYouMixin, LoginRequiredMixin, generic.CreateView): """レポートジャンルを作成する。""" model = ReportInfo template_name='reports/reportInfoCreate.html' form_class = ReportInfoCreateForm def get_success_url(self): return resolve_url('reports:top', self.request.user.id) class reportListView(OnlyYouMixin, LoginRequiredMixin, generic.ListView): """レポート一覧。""" model = Report template_name='reports/reportList.html' paginate_by = 10 ※ここでジャンルIDのinfo_idを設定してテンプレートに渡したい。 def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) try: report_list = Report.objects.get(id=self.kwargs.get['pk']) context['report_list'] = report_list return context except: return context class reportCreateView(OnlyYouMixin, LoginRequiredMixin, generic.CreateView): """レポート作成""" model = Report template_name = 'reports/reportCreate.html' form_class = ReportCreateForm def get_success_url(self): return resolve_url('reports:reportDetail', pk=self.kwargs.get('pk'), id=self.kwargs.get('id'), post_id=self.object.pk)←ここは、適当にコーディングしています。修正の必要あり class reportDetailView(OnlyYouMixin, LoginRequiredMixin, generic.DetailView): """Post表示""" model = Report template_name = 'reports/reportDetail.html'

■models.py

from django.conf import settings from django.db import models from django.contrib.auth.models import User class ReportInfo(models.Model): """ report情報 """ title = models.CharField(max_length=255) text = models.TextField() user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='投稿者') def __str__(self): return self.title class Report(models.Model): """ レポート """ title = models.CharField(max_length=255) text = models.TextField() report = models.ForeignKey(ReportInfo, on_delete=models.CASCADE, verbose_name='レポート') def __str__(self): return self.title

■forms.py

from django import forms from .models import ReportInfo, Report class ReportInfoCreateForm(forms.ModelForm): """記事の作成・更新フォーム""" class Meta: model = ReportInfo fields = '__all__' class ReportCreateForm(forms.ModelForm): """記事の作成・更新フォーム""" class Meta: model = Report fields = '__all__'

■base.html

{% load static %} <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Django Test</title> </head> <body> <div class="container"> <div class="content"> {% block content %}{% endblock %} </div> </div> </body> </html>

■reportInfoList.html

{% extends 'reports/base.html' %} {% block content %} <ul> <li><a href="{% url 'reports:reportInfoCreate' user.pk %}">レポート情報 新規作成</a></li> </ul> Report Info List {% for info in info_list %} <p><a href="{% url 'reports:reportList' user.pk info.id %}"> ユーザーID:{{ info.id }} ユーザー:{{ info.user }} タイトル:{{ info.title }} 内容:{{ info.text }}</a> </p> {% endfor %} {% endblock content %}

■reportInfoCreate.html

{% extends 'reports/base.html' %} {% block content %} Report create <form method="post"> {% csrf_token %} {{ form.as_p }} <input type="submit" value="save"> </form> {% endblock content %}

■reportList.html ※以下のinfo_idにジャンルIDを入れたい!

{% extends 'reports/base.html' %} {% block content %} <ul>   ↓※ このinfo_idが分からない <li><a href="{% url 'reports:reportCreate' user.pk info_id %}">レポート 新規作成</a></li> </ul> Report list report_id: {% for report in report_list %} <p> タイトル:{{ report.title }} 内容:{{ report.text }}</a> </p> {% endfor %} {% endblock content %}

以上、よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

自己解決

自己解決しました。

urls.pyで記載したpk、info_id、report_idはViewのget_context_data(self, **kwargs)の引数のselfのself.kwargsに入っていることが分かりました。
各viewでself.kwargs.get('info_id')やself.kwargs.get('report_id')として現在の値が取得できました。

path('<int:pk>/reportInfo/<int:info_id>/report/<int:report_id>/', views.reportDetailView.as_view(), name='reportDetail'),

投稿2019/10/27 09:40

編集2019/10/27 09:43
koyakoya

総合スコア6

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問