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

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

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

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

MVC

MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

Python 3.x

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

ウェブアプリケーション

ウェブアプリケーションとは、ウェブ上でアクセスされるアプリケーションのことを呼びます。この場合におけるウェブとは、インターネットやイントラネット上を意味します。

Python

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

Q&A

解決済

2回答

6362閲覧

Djangoで、urls.py内のpathに2つのパラメーターを持たせる方法

ak_suzuki

総合スコア194

Django

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

MVC

MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

Python 3.x

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

ウェブアプリケーション

ウェブアプリケーションとは、ウェブ上でアクセスされるアプリケーションのことを呼びます。この場合におけるウェブとは、インターネットやイントラネット上を意味します。

Python

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

0グッド

2クリップ

投稿2019/06/19 13:02

概要

Djangoの学習をしております。

現在、「店」というテーブルを定義しており、その店ごとに毎月の「売上計画」テーブルを持っています。

「店」の詳細ページで、その「店」の「売上計画」の概要をリスト表示し、詳細ボタンをクリックするとその「売上計画」の詳細ページに遷移させようとしています。

URLを、
(1)店の詳細画面: xxx/shop/店名
(2)売上計画の詳細画面 :xxx/shop/店名/売上計画id
というように持たせたいと思い、urls.pyなどを設定しましたが、(1)はうまくできるものの、(2)の売上計画の詳細画面への遷移に、「店名」と「売上計画id」を渡すことが出来ずにエラーになってしまいました。

(2)を「xxx/shop/売上計画id」とすれば出来るの分かるのですが、どうしても階層構造のURL(店の下の階層に計画がある)にしたく、上記のようにしています。

環境

python: 3.7
django: 2.2.x

試したこと

py

1(urls.py) 2from django.urls import path 3 4from . import views 5 6app_name = 'myapp' 7 8urlpatterns = [ 9 path('', views.IndexView.as_view(), name='index'), 10 path('shops/<str:name>', views.ShopDetail.as_view(), name='shop_detail'), 11 path('shops/<str:name>/<int:id>', views.PlanDetail.as_view(), name='plan_detail'), 12]

py

1(views.py) 2from django.conf import settings 3from django.shortcuts import get_object_or_404, render, redirect, resolve_url 4from django.http import HttpResponse 5from django.views import generic 6from django.views.generic import ListView, DetailView, TemplateView 7from .models import Plan, Shop 8 9 10class IndexView(TemplateView): 11 def get(self, request, *args, **kwargs): 12 shop_list = Shop.objects.all() 13 plan_list = Plan.objects.all().order_by('shop', 'month') 14 params = { 15 'shop_list': shop_list, 16 'plan_list': plan_list, 17 } 18 return render(request, 'myapp/index.html', params) 19 20 21 22class ShopDetail(DetailView): 23 model = Shop 24 slug_field = 'name' 25 slug_url_kwarg = 'name' 26 27 def get_context_data(self, *args, **kwargs): 28 plan_list = Plan.objects.filter(shop=kwargs['object']) 29 params = { 30 'plan_list': plan_list, 31 } 32 33 return params 34

html

1(shop_detail.html) 2<!doctype html> 3<html> 4 <head> 5 <meta charset="utf-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> 7 <title>WebAPP</title> 8 </head> 9 <body> 10 <div class="container"> 11 <div class="row"> 12 <div class="col"> 13 <h1>SHOP Detail</h1> 14 <p>Shop名</p> 15 <p>{{ object }}</p> 16 {% for item in plan_list %} 17 <p>{{ item.month }}月: <a href="{% url 'myapp:plan_detail' item.shop item.id %}">詳細をみる</a></p> 18 {% endfor %} 19 </div> 20 </div> 21 </div> 22 </body> 23</html>

上記HTMLで詳細を見るボタンをクリックすると、
Generic detail view PlanDetail must be called with either an object pk or a slug in the URLconf.
というエラーが返ってきます。

ご教授いただけると幸いです。

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

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

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

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

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

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

guest

回答2

0

ベストアンサー

PlanDetail の中身をご提示されていないので正確なことはわからないのですが、 次のメッセージのエラーは、 PlanDetail に対応する URL パターンに pk (あるいは slug )というパラメータが含まれていないために起こっていると推測します。

Generic detail view PlanDetail must be called with either an object pk or a slug in the URLconf.

ですので、 URL パターンの <int:id><int:pk> に変えられるとこのエラーは解消するかと思います。

python

1 path('shops/<str:name>/<int:id>', views.PlanDetail.as_view(), name='plan_detail'),

Django のコードの該当箇所:

ただ、本題の「(2)のパターンを実現したい」ということに関していうと、この場合は function-based view でやられた方がスムーズかなという気がします。

function-based view の擬似コードは次のような感じになるでしょうか(あくまでも擬似コードとして読んでください)。

views.py:

python

1def plan_detail(request, name, pk): 2 # 対応する shop と plan を取得 3 shop = get_object_or_404(Shop, name=name) 4 plan = get_object_or_404(Plan, pk=pk, shop=shop) 5 6 # 両方無事に取得できればページを描画 7 template_name = 'shop/plan/detail.html' 8 context = {'shop': shop, 'plan': plan} 9 return render(request, template_name, context)

urls.py:

python

1 path('shops/<str:name>/<int:pk>', views.plan_detail, name='plan_detail'),

DetailView を利用した class-based view でもやり方次第で実現はできると思いますが、 function-based view の方がシンプル & かんたんに実現できると思います。一度そちらでチャレンジされてみるのはいかがでしょうか。

投稿2019/06/30 01:47

gh640

総合スコア1407

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

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

ak_suzuki

2019/07/01 01:31

ありがとうございます。 「 URL パターンの <int:id> を <int:pk> に変えられるとこのエラーは解消するかと思います。」で解決しました! また、function-base viewに関しての知見もありがとうございます。 なんとなくclass-base view にこだわってしまっていたので、とても参考になりました。
guest

0

エラーを拝見するに、{% url %}でパラメータが認識されてないような印象を受けますね。
Django url tag multiple parameters にパラメータが複数ある時の記述の方法がありました。

shop_detail.html
{% url 'myapp:plan_detail' item.shop item.id %}の部分を
{% url 'myapp:plan_detail' name=item.shop id=item.id %}という風にどれとどれが対応しているかを明示してみたら、認識されるかもしれません。

あとは詳細をみるボタンのhrefの値がレンダリングの結果どんな値になっているかを見ると、原因を推測しやるくなるかと思います。

投稿2019/06/25 16:31

mtitg

総合スコア19

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

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

ak_suzuki

2019/06/29 09:59

ありがとうございます。 教えていただいた内容をもとに試してみました。 まだ解決には至りませんが、少し時間をかけて色々検証してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問