首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >过滤查询集时MultiValueKeyDictError在forms.py中的应用

过滤查询集时MultiValueKeyDictError在forms.py中的应用
EN

Stack Overflow用户
提问于 2019-10-01 11:33:57
回答 1查看 54关注 0票数 2

我试图在forms.py中筛选一个查询集,以便特定的作者(与构建的django用户的关系为1:1)只能查看他们拥有的字符。当我试图过滤除作者以外的任何东西时,一切都很好。当我按作者过滤时,表单最初正确加载,但在POST上我得到了一个MultiValueKeyDictError

以下是错误文本:

代码语言:javascript
复制
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:

代码语言:javascript
复制
@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:

代码语言:javascript
复制
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'])

以及模板本身:

代码语言:javascript
复制
{% 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

代码语言:javascript
复制
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']

很抱歉,如果我错过了任何信息,这是我第一次实际发布而不是仅仅浏览。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-01 11:50:38

您没有正确地覆盖__init__方法。通常,您希望ModelForm参数保持不变,只需将自己的参数添加到kwargs中即可。

代码语言:javascript
复制
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.POSTcur_author unset初始化绑定表单。

您也可以显式地使用cur_author参数,但是在用数据初始化表单时也需要显式地使用data

代码语言:javascript
复制
def __init__(self, cur_author=None, **kwargs)
    super().__init__(**kwargs)  # data is in kwargs
    self.fields['character'].queryset = ...

然后使用CreatePost(data=request.POST)初始化绑定表单,否则数据将分配给cur_author

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58183964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档