Djangoクラスベースのビューは初めてです。投稿の詳細を取得するために単純なビューを作成しようとしています。私のviews.py:
from Django.views.generic import ListView, View, DetailView
class GenreDetail(DetailView):
model = Post
template_name = "post.html"
私のurls.py:
urlpatterns = [
url(r'(?P<post_id>[^/]+)', GenreDetail.as_view(), name = 'post'),
url(r'(?P<post_id>[^/]+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),
]
私が得るエラー:
AttributeError at /2/memoirs-of-a-geisha-by-arthur-golden
Generic detail view GenreDetail must be called with either an object pk or a slug.
したがって、pkまたはslugはGeneric Detailviewに渡されません。それをどのように渡すのですか?私はそれがピックアップできるURLから推測しますが、そうではありません。
uRLパターンは、定義した順序でチェックされます
だからここ:
urlpatterns = [
url(r'(?P<post_id>[^/]+)', GenreDetail.as_view(), name = 'post'),
url(r'(?P<post_id>[^/]+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),
]
...最初のパターンが一致しています($
で終わっていないため、余分なセグメントは無視されます)
...そしてそのパターンは単一のキーワード引数のみを渡します
一般に、同じビューを指す複数のURLパターンを持つことはお勧めできません。可能であれば、特定のビューのURLのさまざまなケースを処理する単一の正規表現(例: optional groups を使用)を作成してみてください。その方がより明確です。
一方、パターンの順序を逆にして、より明示的なパターンを最初に置くことも機能し、正しくなります(これはDjango urlpatternsの規則です!)
urlpatterns = [
url(r'(?P<post_id>[^/]+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),
url(r'(?P<post_id>[^/]+)', GenreDetail.as_view(), name = 'post'),
]
@ozgurが言及しているように、ビューにpk
ではなくpost_id
を使用するように指示する必要もあります pk_url_kwarg
を設定します
Post_idまたはslugを使用して詳細を取得する場合、URLは次のようになります
url(r'post/(?P<post_id>\d+)/$', GenreDetail.as_view(), name = 'post_detail'),
url(r'post/(?P<slug>[-\w]+)/$', GenreDetail.as_view(), name = 'post_detail_slug'),
そしてあなたの見解はこのようになるはずです
from Django.views.generic import DetailView
class GenreDetail(DetailView):
model = Post
template_name = "post.html"
pk_url_kwarg = "post_id"
slug_url_kwarg = 'slug'
query_pk_and_slug = True
詳細は docs をご覧ください。
問題は、オブジェクトを取得するために、デフォルトのDetailView
またはpk
ではなくpost_id
キーワードをURLで使用する必要があることをslug
に通知する必要があることです。それが表示されます。
これは pk_url_kwarg
属性を設定することで実行できます。
(URL定義も間違っています。常に$
でURL定義を終了してください。以下は修正されたバージョンです)
url(r'(?P<post_id>\d+)$', GenreDetail.as_view(), name = 'post'),
url(r'(?P<post_id>\d+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),
次のURLは、上記のURLパターンが与えられた場合に一致します。
from Django.views.generic import DetailView
class GenreDetail(DetailView):
model = Post
template_name = "post.html"
pk_url_kwarg = "post_id"
または、URLでpost_id
をpk
に変更するだけで、ビュー内の何も変更する必要がなくなります。
url(r'(?P<pk>\d+)$', GenreDetail.as_view(), name = 'post'),
url(r'(?P<pk>\d+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),
path を使用:
from Django.urls import path
from . import views
urlpatterns = [
path('<pk>/', views.GenreDetail.as_view(), name="post")]
slug
の場合:
path('<slug:slug>/', views.GenreDetail.as_view(), name="post")