我试图在forms.py中筛选一个查询集,以便特定的作者(与构建的django用户的关系为1:1)只能查看他们拥有的字符。当我试图过滤除作者以外的任何东西时,一切都很好。当我按作者过滤时,表单最初正确加载,但在POST上我得到了一个MultiValueKeyDictError。
以下是错误文本:
MultiValueDictKeyError at /rmi/1/post/new
'cur_author'
Request Method: POST
Request URL: http://127.0.0.1:8000/rmi/1/post/new
Django Version: 3.0.dev20190323160439
Exception Type: MultiValueDictKeyError
Exception Value:
'cur_author'
Exception Location: c:\users\user\desktop\learnpython\django\django\utils\datastructures.py in __getitem__, line 78
Python Executable: C:\.virtualenvs\djangodev\Scripts\python.exe
Python Version: 3.7.2
Python Path:
['C:\\Users\\USER\\Desktop\\rmi',
'C:\\Users\\USER\\AppData\\Local\\Programs\\Python\\Python37\\python37.zip',
'C:\\Users\\USER\\AppData\\Local\\Programs\\Python\\Python37\\DLLs',
'C:\\Users\\USER\\AppData\\Local\\Programs\\Python\\Python37\\lib',
'C:\\Users\\USER\\AppData\\Local\\Programs\\Python\\Python37',
'C:\\.virtualenvs\\djangodev',
'C:\\.virtualenvs\\djangodev\\lib\\site-packages',
'c:\\users\\user\\desktop\\learnpython\\django']views.py:
@login_required
def create_thread(request, board_id):
board_style = 'css/board' + str(board_id) + '.css'
cur_author = get_object_or_404(Author, user=request.user)
if request.method == "POST":
form = CreatePost(request.POST)
if form.is_valid():
post = form.save(commit = False)
post.board = get_object_or_404(Board, pk=board_id)
post.created_at = timezone.now()
post.parent = None
post.save()
return redirect('board', board_id)
else:
data ={
'cur_author': cur_author,
}
form = CreatePost(data)
context ={
'form': form,
'board_id': board_id,
'board_style': board_style,
}
return render(request, 'rmi/create_post.html', context)这是forms.py:
class CreatePost(forms.ModelForm):
class Meta:
model = Post
fields = ['character', 'title', 'content', 'parent']
widgets = {'parent': forms.HiddenInput()}
def __init__(self,cur_author):
super(CreatePost, self).__init__(cur_author)
self.fields['character'].queryset = Character.objects.filter(author=cur_author['cur_author'])以及模板本身:
{% block content %}
<form method="POST" class="create-post" style="margin-top: -2%">
{% csrf_token %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-1 offset-2" style="margin-top:.25%">
<label for="{{ form.character.id_for_character }}">Character</label>
</div>
<div class="col-sm-5">
{{ form.character }}
</div>
</div>
<div class="row">
<div class="col-sm-1 offset-2" style="margin-top:.5%;">
<label for="{{ form.title.id_for_title }}">Subject</label>
</div>
<div class="col-sm-5">
{{ form.title }}
</div>
</div>
<br />
<div class="row">
<div class="col-sm-1 offset-2">
<label for="{{ form.content.id_for_content }}">Message</label>
</div>
</div>
<div class="row">
<div class="col-sm-5 offset-2">
{{ form.content }}
</div>
</div>
</div>
<div class="row" style="margin-top:2%; margin-left:auto; margin-right:auto">
<div class="col-sm-2 offset-2">
<button type="submit" class="button" style="margin-right:2%">Submit Post</button>
</div>
<div class="col-sm-3">
<a class="button" href="{% url 'board' board_id %}">Return to Messages</a>
</div>
</div>
</form>
{% endblock %}我已经特别尝试将cur_author传递给表单,但是当这种情况发生时,我得到了一个TypeError。
TypeError at /rmi/1/post/new
__init__() takes 2 positional arguments but 3 were given
Request Method: POST
Request URL: http://127.0.0.1:8000/rmi/1/post/new
Django Version: 3.0.dev20190323160439
Exception Type: TypeError
Exception Value:
__init__() takes 2 positional arguments but 3 were given
Exception Location: C:\Users\USER\Desktop\rmi\rmi\views.py in create_thread, line 102
Python Executable: C:\.virtualenvs\djangodev\Scripts\python.exe
Python Version: 3.7.2
Python Path:
['C:\\Users\\USER\\Desktop\\rmi',
'C:\\Users\\USER\\AppData\\Local\\Programs\\Python\\Python37\\python37.zip',
'C:\\Users\\USER\\AppData\\Local\\Programs\\Python\\Python37\\DLLs',
'C:\\Users\\USER\\AppData\\Local\\Programs\\Python\\Python37\\lib',
'C:\\Users\\USER\\AppData\\Local\\Programs\\Python\\Python37',
'C:\\.virtualenvs\\djangodev',
'C:\\.virtualenvs\\djangodev\\lib\\site-packages',
'c:\\users\\user\\desktop\\learnpython\\django']很抱歉,如果我错过了任何信息,这是我第一次实际发布而不是仅仅浏览。
发布于 2019-10-01 11:50:38
您没有正确地覆盖__init__方法。通常,您希望ModelForm参数保持不变,只需将自己的参数添加到kwargs中即可。
def __init__(self, *args, **kwargs):
cur_author = kwargs.pop('cur_author', None) # pop custom param before calling super()
super().__init__(*args, **kwargs)
self.fields['character'].queryset = ... # use custom param这是因为ModelForm需要多个参数,而不仅仅是data。这样,您就不会将cur_author添加到data中,这会扰乱您的表单,因为当没有数据时,它应该是不绑定的:form = CreatePost(cur_author=cur_author)将初始化未绑定的表单,form = CreatePost(request.POST)将使用data = request.POST和cur_author unset初始化绑定表单。
您也可以显式地使用cur_author参数,但是在用数据初始化表单时也需要显式地使用data:
def __init__(self, cur_author=None, **kwargs)
super().__init__(**kwargs) # data is in kwargs
self.fields['character'].queryset = ...然后使用CreatePost(data=request.POST)初始化绑定表单,否则数据将分配给cur_author。
https://stackoverflow.com/questions/58183964
复制相似问题