概説
pk(id)は渡っているはずなのになぜかAttributeError at /XXX/<値>/
が出てしまう時は
views.pyのpk_url_kwarg
とurls.pyのパス間で整合性が取れていないことが原因です。
環境
環境は以下の通りです。
名称 | バージョン |
---|---|
macOS | Monterey(12.1) |
django | 4.0.1 |
Python | 3.8.9 |
brew | 3.3.10 |
pip | 21.3.1 |
psycopg2-binary | 2.9.3 |
PostgreSQL | 14.1 |
起きている問題
idはきちんと受け渡して、URLは通っているはずなのに開けずエラーとなってしまいます。
AttributeError at /XXX/<値>/
例外を確認するとGeneric detail view XXXView must be called with either an object pk or a slug in the URLconf.
と出ていますがhtmlでは{{ オブジェクト.pk }}
を読み出せています。
urls.py
from django.urls import path
from . import views
app_name = 'XXX'
urlpatterns = [
...
path('YYY/<pk>/', views.XXXDetailView.as_view(), name='YYY'),
]
対処法
pk_url_kwarg
とpkとして扱いたい文字を統一します。具体的には、urlpatterns
のpath内で使うpkをそのまま使いたい時はView内のフィールドpk_url_kwarg
に変更を加える記述を削除します。また、固有の名称(idなど)としたい場合はurlpatterns
のpath内のpkを固有の名称に書き換えます。
補足
修正例(pkをそのまま使いたい場合)
views.py
...
class XXXDetailView(LoginRequiredMixin, generic.DetailView):
model = Bike
template_name = 'xxx_detail.html'
urls.py
from django.urls import path
from . import views
app_name = 'XXX'
urlpatterns = [
...
path('YYY/<pk>/', views.XXXDetailView.as_view(), name='YYY'),
]
修正例2(固有の名称を使いたい場合)
views.py
...
class XXXDetailView(LoginRequiredMixin, generic.DetailView):
model = XXX
template_name = 'xxx_detail.html'
pk_url_kwarg = 'id' #固有の名称を使いたい場合
urls.py
from django.urls import path
from . import views
app_name = 'XXX'
urlpatterns = [
...
path('YYY/<id>/', views.XXXDetailView.as_view(), name='YYY'),
]