动态更新ModelForm的Meta类

ash*_*her 23 python django metaprogramming django-forms modelform

我希望从我的视图中动态更新ModelForm的内联Meta类.尽管此代码似乎更新在Meta类中的排除列表,从输出as_p(),as_ul()等不反映更新的Meta排除.

我假设在创建ModelForm时不是在as_*()调用时生成html .有没有办法强制更新HTML?

这甚至是最好的方法吗?我只是假设这应该工作.

思考?

from django.forms import ModelForm

from testprogram.online_bookings.models import Passenger

class PassengerInfoForm(ModelForm):

    def set_form_excludes(self, exclude_list):
        self.Meta.exclude = excludes_list

    class Meta:
        model = Passenger
        exclude = []
Run Code Online (Sandbox Code Playgroud)

Dan*_*aab 56

Meta类用于动态构造表单定义 - 因此,在您创建ModelForm实例时,不在排除中的字段已添加为新对象的属性.

执行此操作的常规方法是为每个可能的排除列表提供多个类定义.但是如果你希望表单本身是动态的,你必须动态创建一个类定义.就像是:

def get_form(exclude_list):
    class MyForm(ModelForm):
        class Meta:
            model = Passenger
            exclude = exclude_list
    return MyForm

form_class = get_form(('field1', 'field2'))
form = form_class()
Run Code Online (Sandbox Code Playgroud)

更新:我刚刚重访这篇文章,并认为我会发布一个更惯用的方式来处理动态类:

def PassengerForm(exclude_list, *args, **kwargs):
    class MyPassengerForm(ModelForm):
        class Meta:
            model = Passenger
            exclude = exclude_list

        def __init__(self):
            super(MyPassengerForm, self).__init__(*args, **kwargs)

    return MyPassengerForm()

form = PassengerForm(('field1', 'field2'))
Run Code Online (Sandbox Code Playgroud)

  • +1:动态表单类构造.生病. (3认同)
  • jujule:当然,只需在表单函数中添加一个位置参数:"def PassengerForm(exclude_list,model,*args,**kwargs)",并以与设置Meta.exclude相同的方式设置Meta.model字段. (2认同)
  • @DanielNaab - 有趣。我确实想知道我是否走错了路,但我必须添加 `*args, **kwargs` 才能编辑现有实例;没有 `*args, **kwargs` 将 `instance=object` 传递给表单不起作用(无论如何对我来说) (2认同)

use*_*461 13

其他方式:

class PassengerInfoForm(ModelForm):
    def __init__(self, *args, **kwargs):
        exclude_list=kwargs.pop('exclude_list', '')

        super(PassengerInfoForm, self).__init__(*args, **kwargs)

        for field in exclude_list:
            del self.fields[field]

    class Meta:
        model = Passenger

form = PassengerInfoForm(exclude_list=['field1', 'field2'])
Run Code Online (Sandbox Code Playgroud)

  • 您应该使用{} .pop()而不是设置它然后删除它.exclude_list = kwargs.pop('exclude_list')保存一行代码.*耸肩* (8认同)