当前位置: 首页 > 知识库问答 >
问题:

当实例也被给定时,如何为ModelForm设置初始值

逄宁
2023-03-14

似乎如果一个ModelForm给定了一个实例,它会忽略您为<code>initial<code>提供的任何值,而是将其设置为实例的值——即使该实例是一个空的模型记录。

有没有办法创建一个带有实例的表单,并让它设置初始数据?

我之所以需要它,是因为我正在保存相关记录,除非在创建时给ModelForm一个实例,否则它们看起来不会正确保存。

我相信这个问题的答案是直截了当的,我只是遗漏了一些显而易见的东西。

以下是相关代码:

form = form_class(person=person, conference=conference, initial=initial, instance=registration)

其中form_class是< code>RegistrationForm,然后在注册表中:

class RegisterForm(forms.ModelForm):
    ... fields here ...

    def __init__(self, *args, **kwargs):
        ... other code ...
        self.person = kwargs.pop('person')
        super(RegisterForm, self).__init__(*args, **kwargs)
        for key, in self.fields.keys():
            if hasattr(self.person, key):
                self.fields[k].initial = getattr(self.person, key)

然后,当我调用该字段时,相关字段为空。

共有3个答案

商瀚
2023-03-14

您还可以在初始化类时将额外的变量传递给类。然后,您传递的值可以覆盖初始或POST数据。

class RegisterForm(forms.ModelForm):
    ... fields here ...

    def __init__(self, person, conference, *args, **kwargs):
        ... other code ...
        super(RegisterForm, self).__init__(*args, **kwargs)
        self.fields['person'] = person
        self.fields['conference'] = conference

form = RegisterForm(person, conference, initial=initial, instance=registration)
鲍鸿波
2023-03-14

在我看来,您可能正在寻找一个绑定表单。不完全确定,我正在尝试解开一个类似的问题:

Django表单可以用两个参数实例化,这两个参数控制这类事情。据我所知:

form = MyForm(initial={...}, data={...}, ...)

initial将设置字段的可能值,如设置queryset数据将设置表单的实际(或选定)值并创建绑定表单。这可能是您想要的。你可能会发现有趣的另一点是考虑工厂方法而不是构造函数,我认为语法更自然:

class MyForm(forms.ModelForm):

    ...

    @staticmethod
    def makeBoundForm(user):
        myObjSet = MyObject.objects.filter(some_attr__user=user)
        if len(myObjSet) is not 0:
            data = {'myObject': myObjSet[0]}
        else:
            raise ValueError()
        initial = {'myObject': myObjSet}
        return MyForm(initial=initial, data=data)
闻鹤龄
2023-03-14

在谷歌上搜索了一下后发现了这一点。

您必须在调用< code>super之前设置初始值。

因此,我不必遍历self.fields.keys(),而是必须键入我想要的字段列表并循环遍历它:

class RegisterForm(forms.ModelForm):
    ... fields here ...
    initial_fields = ['first_name', 'last_name', ... ]

    def __init__(self, *args, **kwargs):
        ... other code ...
        self.person = kwargs.pop('person')
        for key in self.initial_fields:
            if hasattr(self.person, key):
                self.fields[k].initial = getattr(self.person, key)
        super(RegisterForm, self).__init__(*args, **kwargs)

@Daria正确地指出,在调用Super之前,您没有self.fields。我很确定这将起作用:

class RegisterForm(forms.ModelForm):
    ... fields here ...
    initial_fields = ['first_name', 'last_name', ... ]

    def __init__(self, *args, **kwargs):
        ... other code ...
        initial = kwargs.pop('initial', {})
        self.person = kwargs.pop('person')
        for key in self.initial_fields:
            if hasattr(self.person, key):
                initial[key] = initial.get(key) or getattr(self.person, key)
        kwargs['initial'] = initial
        super(RegisterForm, self).__init__(*args, **kwargs)

在这个版本中,我们使用<code>initial

 类似资料:
  • 问题内容: 什么时候实例变量被初始化?是在构造函数块完成之后还是之前? 考虑以下示例: 家长建设者 子init() 父Init() 儿童构造者 属性1:100 属性2:null 什么时候在堆中分配属性1和2的内存? 好奇地知道为什么属性2为NULL? 有设计上的缺陷吗? 问题答案: 什么时候在堆中分配属性1和2的内存? 整个对象的内存是在调用构造函数之前在调用运算符时分配的。在中为单个实例分配了内

  • 问题内容: 我正在使用基于类的通用视图,有人可以建议我如何设置初始值以更新表单吗? 我尝试使用get_initial()方法,但未成功。以下是我尝试的代码 问题答案: 您应该定义一个方法,该方法返回包含初始值的字典: 另外,您可以定义一个值:

  • 问题内容: 在我的Django(1.2)项目中,我想以模型形式预填充字段,但是新值将被忽略。这是代码段: 我也尝试了使用,但没有效果:总是在表单中显示数据库值。有任何想法吗? 问题答案: 尝试这个:

  • 当安装完成并首次启动 Navicat Monitor 时,浏览器会弹出并打开你的 Navicat Monitor 的网址“http://<your_ip_address>:<port_number>”。你需要在欢迎页面完成 Navicat Monitor 的基本配置。 【注意】<your_host_address> 是安装了 Navicat Monitor 的系统的主机名,以及 <port_num

  • 我正在使用Flink 1.3.2和scala构建一个流媒体应用程序,我的Flink应用程序将监视一个文件夹,并将新文件流到管道中。文件中的每条记录都有一个相关的时间戳。我想使用此时间戳作为事件时间,并使用AssignerWithPeriodicWatermarks构建水印,我的水印生成器如下所示: 但是,由于我的文件夹中有一些旧数据,我不想处理它们。旧文件中记录的时间戳是

  • 可让PS Vita系统软件的设定回复初始设定,使主画面及开始画面皆回到至购买时的状态。 轻触[格式化]>[初始化设定]。请遵循画面指示正确操作。 重要 初始化设定后无法复原,请注意。 初始化中请勿关闭PS Vita的电源。初始化若遭到中断,可能会导致故障。 即使进行此操作,也无法让系统软件回到先前版本。