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 }}
。
我可能在做一些愚蠢的事情,但无法弄清楚是什么,这让我发疯,因为它微不足道,而且我还有其他应用程序使用相同的逻辑。
所以我有一个模型客户和模型注释。每个客户我都可以创建很多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 }}
。