【问题标题】:How to choose form depending on model field如何根据模型字段选择表格
【发布时间】:2016-03-25 04:26:02
【问题描述】:

我有一个 django 模型来定义内容页面,在该模型中我有一个字段可以选择是否希望某些表单出现在页面中。

现在我制作了第二个表格。我想根据ContentPage 实例中填写的某些字段来使用一个或另一个。

更具体地说,我坚持这部分:

class ViewContentPage(CreateView):
    model = ContentPage
    # What I'd like to do
    form_class = depending_on_some_ContentPage_field()

    # From here, overriden methods and stuff

问题是似乎无法访问kwargsrequest 在类级别定义(为了根据从 kwargs 中提取的 slug 加载正确的 ContentPage 记录,然后从它的字段中确定要加载的表单)

我一直在考虑不同的方法来获得类似的结果,这项研究让我找到了这个问题:Can I call a view from within another view?。我在想“将 FormViews 作为 ViewContentPage 中的子视图”会铺平道路,或者为在模板级别呈现的表单提供完全独立的视图......

上面的伪代码中暴露的东西可以用其他方法实现吗?

编辑

正如@Alasdair 建议的那样,我认为我会覆盖get_form_class() 方法。它看起来像我想要的那样,但是完全在 Django 本身中追溯的一个小故障阻碍了我。

我使用 Django v1.8.3,引发异常的点在 django.core.handlers.base.py 第 132 行(回溯中的第一个)。例外是:

TypeError: 'instance' 是此函数的无效关键字参数

这个异常的原因似乎在django/db/models/base.py 第480行(最后在回溯中)。不知何故,这个类(django.db.models.base.Model)正在运行,即使self = Error in formatting: RelatedObjectDoesNotExist: MyModelForForm2 has no page. 真的很混乱。

这不是我第一次看到追溯不会在我的源中的任何地方停止的错误,即使如此,更正源将消除错误。但是,我仍然坚持如何在不修改 Django 本身的情况下纠正这个问题。

【问题讨论】:

  • 我不鼓励查看“子视图”方法。由于您使用的是 Python,因此 可能 从另一个视图中调用基于类的视图,但我认为我不会推荐这种方法。自定义基于类的视图功能的最佳方法是覆盖适当的方法或属性。

标签: python django django-models django-forms


【解决方案1】:

您可以覆盖get_form_class 方法。在其中,您可以访问self.request 并从self.kwargs 获取slug。

class ViewContentPage(CreateView):
    model = ContentPage

    def get form_class(self):
        # return correct class based on self.kwargs and self.request

【讨论】:

  • 好主意。我尝试实现它直接根据字段返回所需的表单类,而不需要任何super() 调用。它触发了我TypeError: 'instance' is an invalid keyword argument for this function,并且回溯甚至不会在我的源代码中停止。无论如何,谢谢,我认为这是要走的路。
  • 我不知道为什么您在没有看到回溯的情况下获得TypeError。您不必在get_form_class 中调用super()
  • 没关系。这只是为了不要忘记它。不知何故,我会找到一种方法来防止这个错误。
  • 天哪,卡住了将近 2 个小时,因为在 get_form_class() 我返回的是模型实例而不是表单! :-$ 找到这个滑出后,你的建议就像一个魅力!非常感谢您的帮助。顺便说一句,似乎以某种方式更新我的问题与Rubber Duck Debugging 一样有效... xD
猜你喜欢
  • 2021-01-30
  • 1970-01-01
  • 2023-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-03
  • 1970-01-01
相关资源
最近更新 更多