更新实例时Django表示字段初始值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了更新实例时Django表示字段初始值相关的知识,希望对你有一定的参考价值。

我有一个自定义Django ModelForm,我用它来更新模型实例。 这是示例模型:

class MyModel(models.Model):
    number = models.CharField(_("Number"), max_length=30, unique=True)
    sent_date = models.DateField(_('Sent date'), null=True, blank=True)

在创建实例时,我将只传递number字段,这就是为什么我不想要sent_date

然后我有一个视图,使用此自定义窗体更新sent_date字段:

# Generic form updater
class MyModelUpdateForm(forms.ModelForm):
    class Meta:
        model = MyModel
        fields = []

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

        # Make fields mandatory
        if hasattr(self, 'required_fields'):
            for field_name in self.required_fields:
                self.fields[field_name].required = True
        # Set initial values
        if hasattr(self, 'initial_values'):
            for field_name, value in self.initial_values.items():
                self.initial[field_name] = value


class SentForm(MyModelUpdateForm):
    required_fields = ['sent_date']
    initial_values = {'sent_date': datetime.date.today()}

    class Meta(MyModelUpdateForm.Meta):
        fields = ['sent_date']
        field_classes = {'sent_date': MyCustomDateField}

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

MyModelUpdateFormSentForm等具体形式的通用祖先。

在我的视图中,每当有GET我手动实例化表单时:

my_form = SentForm({instance: my_model_instance})

所以在这种情况下,我希望sent_date字段的初始值设置为今天的日期,即使实际模型实例字段为None也很难。

如果我检查my_form对象,它确实具有以下属性:

initial: {'sent_date': datetime.date(2018, 3, 1)}
instance: my_model_instance
fields: {'sent_date':
            ...: ...,
            'initial': None # Why this is None?
            ...: ... 
         }

所以显然它应该工作,但事实并非如此:该领域总是空的。

所以我怀疑这个价值来自my_model_instance.sent_date,实际上是None

initial['sent_date'] = datetime.date(2018, 3, 1)是正确的。 在另一边fields['sent_date']['initial'] = None它不是。

initialmy_model_instance.sent_date时,我怎么能总是显示None值?

答案

显然我已经解决了:

class MyModelUpdateForm(forms.ModelForm):
    class Meta:
        model = MyModel
        fields = []

    def __init__(self, *args, **kwargs):
        initial = kwargs.get('initial', {})
        if hasattr(self, 'initial_values') and not kwargs.get('data'):
            for field_name, value in self.initial_values.items():
                if not getattr(kwargs.get('instance', None), field_name, None):
                    initial[field_name] = value
            kwargs.update({'initial': initial})
        super().__init__(*args, **kwargs)

        # Make fields mandatory
        if hasattr(self, 'required_fields'):
            for field_name in self.required_fields:
                self.fields[field_name].required = True

即使很难有效,如果有人有任何问题,我也不会介意一个不太讨厌的解决方案:)

另一答案

我在我的应用程序的许多地方都有这个案例,没有任何问题。但是,我使用不同的方法来设置现有实例的某些字段的初始值。代替:

self.initial[field_name] = value

我打电话给super()后写道:

self.fields[field_name].initial = value

你能尝试告诉结果吗?

以上是关于更新实例时Django表示字段初始值的主要内容,如果未能解决你的问题,请参考以下文章

Django REST框架--认证和权限

如何在渲染django模板时动态设置表单选择字段的初始值

Django - UpdateView ModelForm 在查询集字段上设置初始值

使用自定义模板时 Django 表单字段的初始值

如何动态更新ModelForm的初始值?

更新中带有小部件的 Django Form DateInput:丢失初始值