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

Ily*_*bik 2 python django keyerror

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

所以我有一个模型客户和模型说明.每个客户我都可以创建很多Notes.在Notes中,Customer定义为外键.

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})
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

所以表格显示确定,点击保存后我就收到了

KeyError at/customer/note/new/9'pk'请求方法:POST请求URL:http://127.0.0.1:8000/customer/note/new/9 Django版本:1.8异常类型:KeyError异常值:
'pk '异常位置:C:\ Users\I812624\dev\mrp\src\customer\forms.py in __init__,第48行Python版本:2.7.1

它应该将我重定向到contact_details,其中显示联系信息并且它遍历所有Notes.

contact_details.html

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

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

    </tr>
    {% endfor %}
Run Code Online (Sandbox Code Playgroud)

有什么建议?

谢谢 .

Ala*_*air 6

@Shang已经解释了为什么你会收到错误以及如何解决它,所以我不再重复了.我的答案是在你看来建议一种不同的方法.

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

class NoteForm(forms.ModelForm):
        class Meta:
            model = Note
            fields = [ 'title','body']
Run Code Online (Sandbox Code Playgroud)

然后在您的视图中,您可以在保存后设置联系人 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)
Run Code Online (Sandbox Code Playgroud)

现在你根本不必覆盖表单的__init__方法.

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

return render(request, 'customer/note_edit.html', {'form': form, 'contact': contact})
Run Code Online (Sandbox Code Playgroud)

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


Sha*_*ang 5

这是因为您尝试以表格形式执行此操作__init__

contact_id = kwargs.pop('pk')
Run Code Online (Sandbox Code Playgroud)

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

form = NoteForm(request.POST, pk=pk)
Run Code Online (Sandbox Code Playgroud)

避免出现异常的一种更安全的方法是将default参数用于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
Run Code Online (Sandbox Code Playgroud)