【问题标题】:Limiting choices in foreign key dropdown in Django using Generic Views ( CreateView )使用通用视图( CreateView )限制 Django 中外键下拉列表中的选择
【发布时间】:2018-01-04 06:07:31
【问题描述】:

我有两个模型:

第一个:

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 创建表单以进行值填充:

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

然后使用它在模板中呈现这些字段。

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

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

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

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

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

谢谢..

(请随时提出更正建议。)

【问题讨论】:

    标签: python django


    【解决方案1】:

    您可以在视图的form_valid 中访问self.request.user。但是为了限制表单中的选择,您必须在最初提供表单之前对其进行自定义。您最好覆盖视图的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. 如果选项不需要您的数据、用户或表单实例的运行时知识,并且在可能使用模型表单的每个上下文中都是相同的,您可以在 ForeignKey 字段本身上设置 limit_choices_to ;作为模块级代码,这在模块导入时被评估一次。每次呈现表单时都会构建并执行相应的查询。

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

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

    【讨论】:

    • 成功了。非常感谢您的快速响应和出色的解决方案。当我得到 15 次代表时,我会投票。
    【解决方案2】:

    @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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-07
      • 2018-12-13
      • 2011-03-05
      • 2015-07-04
      • 1970-01-01
      • 2016-10-13
      • 2018-04-21
      • 2011-08-11
      相关资源
      最近更新 更多