Django 异常类型:KeyError 异常值:'pk'

Django Exception Type: KeyError Exception Value: 'pk'

我可能在做一些愚蠢的事情,但无法弄清楚是什么,这让我发疯,因为它微不足道,而且我还有其他应用程序使用相同的逻辑。

所以我有一个模型客户和模型注释。每个客户我都可以创建很多Notes。 在 Notes 中,客户被定义为外键。

view.py

@login_required
def note_new(request,pk):
    contact = get_object_or_404(Contacts, pk=pk)
    if request.method == "POST":
        form = NoteForm(request.POST)
        if form.is_valid():
            note = form.save(commit=False)
            note.pub_date = timezone.now()
            note.save()
            return redirect('contact_details',pk=contact.id)
    else:
        form = NoteForm(pk=contact.id)
    return render(request, 'customer/note_edit.html', {'form': form})

forms.py

class NoteForm(forms.ModelForm):
    class Meta:
        model = Note
        fields = [ 'title','body','contact' ]

    def __init__(self,*args,**kwargs):
        contact_id = kwargs.pop('pk')
        # self.fields['contact'].initial = contact_id
        super(NoteForm,self).__init__(*args,**kwargs)
        self.initial['contact'] = contact_id
        self.fields['contact'].widget.attrs['readonly'] = True

所以表单显示正常,在我点击保存后我得到

KeyError at /customer/note/new/9 'pk' Request Method: POST Request URL: http://127.0.0.1:8000/customer/note/new/9 Django Version: 1.8 Exception Type: KeyError Exception Value:
'pk' Exception Location: C:\Users\I812624\dev\mrp\src\customer\forms.py in __init__, line 48 Python Version: 2.7.1

它应该将我重定向到显示联系信息的 contact_details,它会遍历所有笔记。

contact_details.html

 {% for field in data.notes %}
    <tr>

       <td> {{ field }}</td>

    </tr>
    {% endfor %}

有什么建议吗?

谢谢。

这是因为您尝试在您的表单中执行此操作 __init__:

contact_id = kwargs.pop('pk')

但是在您的 views.py 方法中您没有将它传递给表单构造函数。更改 note_new 方法以传递 pk 形式:

form = NoteForm(request.POST, pk=pk)

避免异常的更安全方法是使用 pop:

的默认参数
contact_id = kwargs.pop('pk', None)
super(NoteForm,self).__init__(*args,**kwargs)
if contact_id:
    # do something if pk is passed, otherwise contact_id is None

@Shang 已经解释了错误的原因和解决方法,不再重复。我的回答是建议您采用不同的方法。

如果您不希望 contact 字段可编辑,最好将其从表单中排除。

class NoteForm(forms.ModelForm):
        class Meta:
            model = Note
            fields = [ 'title','body']

那么在你看来,保存后可以设置联系人commit=False

    if form.is_valid():
        note = form.save(commit=False)
        note.pub_date = timezone.now()
        note.contact = contact
        note.save()
        return redirect('contact_details', pk=contact.id)

现在您根本不必重写表单的 __init__ 方法。

如果要在模板中显示 contact,请将其包含在模板上下文中。

return render(request, 'customer/note_edit.html', {'form': form, 'contact': contact})

然后在模板中包含 {{ contact }}