Django错误NoReverseMatch,因为它错过了一个pk

时间:2018-05-03 13:30:45

标签: python django

所以目前我正在一个有这样的网址链接的网页上

urls.py:

path('key/<int:pk>', views.KeyDetailView.as_view(), name='roomkey-detail'),

views.py:

class KeyDetailView(generic.DetailView):
    model = RoomKey

这列出了可用于特定房间的密钥列表。然后,当我尝试前往下一页时,我可以在哪里请求借用该房间的其中一个键,以下是负责呈现roomkey-request页面的URL和视图

urls.py:

path('key/<int:pk>/request', views.KeyRequestCreate.as_view(), name='roomkey-request')

views.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'),

views.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的请求页面吗?我想我只是对网址如何处理pk以及如何传递它感到困惑。我认为这与某些关键协议无法从详细信息页面中获取的内容有关,有人可以向我解释我做错了什么或指向我一些资源,可以帮助我了解网址如何从视图传递到视图?我是django的新手,所以感谢您提前帮助!!

2 个答案:

答案 0 :(得分:1)

尝试:

def KeyAgreement(request, pk):  #-->pk in argument

    return render(
        request,
        'catalog/roomkey_agreement.html',
    )

答案 1 :(得分:1)

如果您想在roomkey.pk模板中使用roomkey_request_form.html,则需要将roomkey添加到模板上下文中。您可以使用get_context_data方法执行此操作。

由于您已经从网址获得了房间密钥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>

然后,您需要在模板上下文中包含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以匹配推荐的样式。您还需要更新网址格式。

path('key/<int:pk>/request/agreement', views.KeyAgreement, name='key-agreement'),