【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 %}
以上、よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。