python - Django 错误 NoReverseMatch 因为它缺少一个 pk
问题描述
所以目前我在一个带有这样的 url 链接的页面上
urls.py:
path('key/<int:pk>', views.KeyDetailView.as_view(), name='roomkey-detail'),
视图.py:
class KeyDetailView(generic.DetailView):
model = RoomKey
这列出了可用于特定房间借用的钥匙列表。然后,当我尝试前往下一页时,我可以在哪里提出借用该房间的其中一个钥匙的请求,这是负责呈现房间钥匙请求页面的 url 和视图
urls.py:
path('key/<int:pk>/request', views.KeyRequestCreate.as_view(), name='roomkey-request')
视图.py:
class KeyRequestCreate(CreateView):
model = KeyRequest
fields = ['roomkey', 'requester', 'borrower', 'request_comments']
template_name = 'catalog/roomkey_request_form.html'
该页面上有一个按钮,链接到如下所示的条款和协议页面
roomkey_request_form.html:
<a href="{% url 'key-agreement' roomkey.pk %}">terms and conditions</a>
urls.py:
path('key/<int:pk>/request/agreement', views.KeyAgreement, name='key-agreement'),
视图.py:
def KeyAgreement(request):
return render(
request,
'catalog/roomkey_agreement.html',
)
但是,当尝试单击该请求按钮以请求密钥时,django 会引发错误
NoReverseMatch at /catalog/key/2/request
Reverse for 'key-agreement' with arguments '('',)' not found. 1 pattern(s)
tried: ['catalog\\/key\\/(?P<pk>[0-9]+)\\/request\\/agreement$']
我在条款和协议上有一个按钮,可以返回请求页面,看起来像这样
<button href="{% url 'roomkey-request' roomkey.pk %}" >Return to request</button>
这会以正确的pk返回请求页面吗?我想我只是对 url 如何处理 pk 以及它如何传递感到困惑。我认为这与 keyagreement 无法从详细信息页面中获取该 pk 的某些事情有关,有人可以向我解释我做错了什么或指向一些可以帮助我了解 url 如何在视图之间传递 pk 的资源?我对 django 很陌生,所以提前感谢您的帮助!
解决方案
如果要roomkey.pk
在roomkey_request_form.html
模板中使用,则需要添加roomkey
到模板上下文中。您可以在get_context_data
方法中执行此操作。
由于您已经从 URL 中获得了 roomkey pk,因此您可以将其从fields
. 然后在保存前roomkey
的form_valid
方法中设置。
class KeyRequestCreate(CreateView):
model = KeyRequest
fields = ['requester', 'borrower', 'request_comments']
template_name = 'catalog/roomkey_request_form.html'
def get_context_data(self, **kwargs):
context = super(KeyRequestCreate, self).get_context_data(**kwargs)
context['roomkey'] = get_object_or_404(RoomKey, pk=pk)
def form_valid(self, form):
form.instance.roomkey = get_object_or_404(RoomKey, pk=pk)
return super(KeyRequestCreate, self).get_form(form)
如果您想roomkey
在协议视图中使用,您还必须对其进行一些更改。
首先,您需要添加pk
到函数签名中,因为您<int:pk>
在其 URL 模式中有。
然后,您需要包含roomkey
在模板上下文中。
from django.shortcuts import get_object_or_404
def key_agreement(request, pk):
roomkey = get_object_or_404(roomkey, pk=pk)
return render(
request,
'catalog/roomkey_agreement.html',
{'roomkey': roomkey}
)
请注意,我已重命名视图函数key_agreement
以匹配推荐的样式。您还需要更新 URL 模式。
path('key/<int:pk>/request/agreement', views.KeyAgreement, name='key-agreement'),