通过ModelMultipleChoiceField将请求传递给表单,Django

时间:2019-05-12 13:26:10

标签: django django-forms

我想将基于类的视图中的request.user或request.user.pk传递给ModelForm,以便使用request.user.pk过滤查询集。 我有以下看法:


class ArticleResurrectionView(MessageLoginRequiredMixin, FormView):
    model = Article
    form_class = ArticleResurrectionForm
    template_name = "articles/resurrection.html"
    success_url = reverse_lazy("articles:articles_main")
    redirect_message = "You have to be logged in to recover articles "

    def get_form_kwargs(self):
        kwargs = FormView.get_form_kwargs(self)
        kwargs["author_id"] = self.request.user.pk
        return kwargs

def get_form_kwargs(self):应将self.request.user.pk作为kwargs [“ author_id”]传递给表单的 init

然后,我对此视图具有以下形式:

class ArticleResurrectionForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        self.author_id = kwargs.pop("author_id", None)
        forms.ModelForm.__init__(self, *args, **kwargs)


    title = forms.ModelMultipleChoiceField(label="Deleted articles", 

help_text="Please select the    article to recover", 

queryset=Article.default.filter(show=False, author=???) )

# I can not use self.author_id  here

目标是使用标题中的 init 中的self.author_id来过滤查询集,从而显示仅由当前用户输入的条目。换句话说,我需要在title的queryset中传递self.author_id。

也许可以通过类似的方式做到这一点:

def __init__(self, *args, **kwargs):
        self.author_id = kwargs.pop("author_id", None)
        forms.ModelForm.__init__(self, *args, **kwargs)
        self.fields[“title"].queryset = ???

无论如何,如果您知道如何在查询集中获取request.user,那么我将很高兴为您提供解决方案。 谢谢!

关于相关管理器的

p.s:“默认”而不是标准的“对象”,我使用2个管理器:


class ArticleManager(models.Manager):
    """Shows only non deleted articles"""
    def get_queryset(self):
        return models.Manager.get_queryset(self).exclude(show=False)


class Article(models.Model):
    # related managers
    default = models.Manager() # shows all articles
    objects = ArticleManager() # shows only non deleted articles
.....
.....
.....

2 个答案:

答案 0 :(得分:1)

您的第二种方法确实是正确的方法,尽管您可能想使用ModelChoiceField [Django-doc]而不是ModelMultipleChoiceField [Django-doc],因为后者允许您选择 multiple 这样的{ {1}},但您的表单逻辑(Article)暗示它是单数。

title

因此,我们最初将queryset指定为空,但后来通过在表单的构造函数中指定另一个queryset对此进行了修补。

对于您的视图,您可能希望进行class ArticleResurrectionForm(forms.ModelForm): title = forms.ModelChoiceField( queryset=Article.objects.none() label='Deleted articles', help_text='Please select the article to recover' ) def __init__(self, *args, **kwargs): author_id = kwargs.pop("author_id", None) forms.ModelForm.__init__(self, *args, **kwargs) self.fields['title'].queryset = Article.objects.filter( author_id=author_id, show=False )调用而不是调用特定类的方法,例如:

super()

答案 1 :(得分:0)

将 request.user 添加到您的表单实例

form = FormItemForm(request.POST or None, request.user)

然后在你的 form.py 中添加这个

field = forms.ModelMultipleChoiceField(
        widget=forms.CheckboxSelectMultiple,
        queryset=Field.objects.none(),
        label='Fields',
        help_text='Please select a field.'
    )

def __init__(self, *args, **kwargs):
        us = args[1] or None
        forms.ModelForm.__init__(self, *args, **kwargs)
        self.fields['field'].queryset = Field.objects.filter(user=us)

试试看是否有效。对我来说效果很好。