使用通用视图(CreateView)

时间:2018-01-04 06:07:32

标签: python django

我有两种模式:

第一个:

class A(models.Model):
    a_user = models.ForeignKey(User, unique=False, on_delete=models.CASCADE)
    a_title = models.CharField("A title", max_length=500)

第二个:

class B(models.Model):
    b_a = models.ForeignKey(A, verbose_name=('A'), unique=False, on_delete=models.CASCADE)
    b_details = models.TextField()

现在,我正在使用CreateView为Value填充创建表单:

class B_Create(CreateView):
    model = B
    fields = ['b_a','b_details']

然后使用它在模板中渲染这些字段。

现在,我的问题是,在给出字段 b_a (这是下拉列表)的同时,它列出了模型A的所有值,但是需要只列出模型A ,属于特定登录用户,位于下拉列表中。

我已经看到了所有的答案,但仍然无法解决问题。 我尝试过的事情:

    模型中的
  • limit_choices_to :无法在limit_choices中传递A的值
  • form_valid :在CreateView中没有模型A,因为在B_Create中只有B是参考模型
  • 通过网址在模板中传递A的主键:然后模板中没有A的实例,因此无法访问。另外,不想在模板中处理它。

我是Django的新手还在学习,所以不知道要覆盖管理员表单。

如果可能的话,请建议实施方式。我研究并尝试了大多数类似的问题而没有针对我的特定问题的结果。我觉得,这是一个愚蠢的问题,但我被困在这里,所以需要帮助。

谢谢..

(请随时建议更正。)

2 个答案:

答案 0 :(得分:1)

您可以在视图的self.request.user中访问form_valid。但是为了限制表单中的选择,您必须在最初提供表单之前自定义表单。您最好覆盖视图的get_form并设置表单字段queryset

class B_Create(CreateView):
    model = B
    fields = ['b_a','b_details']

    def get_form(self, *args, **kwargs):
        form = super(B_Create, self).get_form(*args, **kwargs)
        form.fields['b_a'].queryset = self.request.user.a_set.all()
        # form.fields['b_a'].queryset = A.objects.filter(a_user=self.request.user) 
        return form

通常,有三个地方可以影响ModelChoiceField的选择:

  1. 如果选择不需要您的数据,用户或表单实例的运行时知识,并且在可能使用模型的每个上下文中都相同,则可以在{{1}上设置limit_choices_to字段本身;作为模块级代码,在模块导入时评估一次。每次呈现表单时都会构建并执行相应的查询。

  2. 如果选项不需要运行时知识,但可能在不同的表单中有所不同,则可以使用自定义ForeignKey并在相应表单字段的字段定义中设置ModelForms。< / p>

  3. 如果查询集需要任何运行时信息,您可以覆盖自定义表单的queryset并将其传递给设置字段查询集所需的任何信息,或者只是在之后修改表单上的查询集创建它通常是一个更快的修复,django的默认视图提供了很好的钩子(参见上面的代码)。

答案 1 :(得分:0)

@schwobaseggl的答案非常好。

这是Python 3版本。我需要根据登录用户限制项目下拉菜单输入。

class ProductCreateView(LoginRequiredMixin, CreateView):
    model = Product
    template_name = 'brand/product-create.html'
    fields = '__all__'

    def get_form(self, form_class=None):
        form = super().get_form(form_class=None)
        form.fields['project'].queryset = form.fields['project'].queryset.filter(owner_id=self.request.user.id)
        return form