使用 django cleaned data pop 在提交到 db 之前删除数据
using django cleaned data pop to remove data before commit to db
我有一个带有 select 列表的表单。
当用户 select 从 award_grant_type
select 列表中输入 8888 或 9999 的值时,我想要表单输入字段中可能存在或不存在的一些数据(用户可能已经在表单文本输入字段中输入了数据,然后 selected 8888 或 9999)在表单数据提交到数据库之前被删除。
所以我有以下 model.py 代码:
.....
DISPLAY_ONLY_AWARD_AND_GRANT_DESCRIPTION_WITH_PROMPT = 8888
DISPLAY_ONLY_AWARD_AND_GRANT_DESCRIPTION_WITHOUT_PROMPT = 9999
.....
AWARD_GRANT_TYPES = (
(SELECT_AWARD_AND_GRANT_TYPE, _('Select Type')),
(AWARD, _('Award')),
(GRANT, _('Grant')),
(TRAVEL_GRANT, _('Travel Grant')),
(OTHER_AWARD, _('Other Award')),
(OTHER_GRANT, _('Other Grant')),
(WRITE_MY_OWN_AWARD_AND_GRANT_TYPE_DESCRIPTION, _('Write my own Type description')), #7777
(DISPLAY_ONLY_AWARD_AND_GRANT_DESCRIPTION_WITH_PROMPT, _('Display only Description with prompt')), #8888
(DISPLAY_ONLY_AWARD_AND_GRANT_DESCRIPTION_WITHOUT_PROMPT, _('Display only Description without prompt')) #9999
)
user = models.ForeignKey(User)
language_version = models.ForeignKey('LanguageVersion')
award_grant_type = models.PositiveIntegerField(choices=AWARD_GRANT_TYPES, default=SELECT_AWARD_AND_GRANT_TYPE, validators=[MinValueValidator(1)])
award_grant_type_description = models.CharField(null=True, blank=True, max_length=250)
award_grant_date = models.DateField(null=True, blank=True)
award_grant_description = models.TextField(null=False, blank=False, max_length=5000)
这是我的 forms.py 干净代码,当用户从 select 中输入 8888 或 9999 时,应该删除 award_grant_type_description
和 award_grant_date
字段] 在提交到数据库之前列出 award_grant_type
:
def clean(self):
cd_agdf = super(AwardGrantDetailsForm, self).clean()
if 'award_grant_type' in cd_agdf:
if cd_agdf['award_grant_type'] == '':
self._errors['award_grant_type'] = self.error_class([_("You must select a Type.")])
elif cd_agdf['award_grant_type'] == 8888 or cd_agdf['award_grant_type'] == 9999:
# remove the entered values when the award grant type only requires minimum data.
self.cleaned_data.pop('award_grant_type_description', None)
self.cleaned_data.pop('award_grant_date', None)
else:
....
return cd_agdf
任何人都可以指出我做错了什么吗? 在表单数据提交到数据库之前,award_grant_type_description
和 award_grant_date
没有被删除。
编辑/更新
只有在更新现有记录时才会出现此问题。在将表单保存到数据库之前,新记录会根据需要删除数据。当现有记录有一个日期字段作为数据库记录的一部分并且 award_grant_type
从 1 更改为 8888 或 9999 时,award_grant_date
不会从数据库中删除。我想不通为什么。
第二次编辑
我已经发布了一个相关主题 。
尝试将 self.cleaned_data
更改为 cd_agdf
。字典,那个方法clean
returns,将被用作cleaned_data
。您从 self.cleaned_data
中弹出项目,但返回时未更改 cd_ahdf
。这被描述为 here(请参阅以 "The form's subclass..." 开头的最后一步)。
而不是self.cleaned_data.pop()
在将 cd_agdf
分配给 superclass
时执行 cd_agdf.pop()
仅回答编辑:数据的含义存在争议。
表单验证首先发生,其目的是解析提交的数据,清理数据并指出数据中的任何错误。此步骤的结果应该是数据的清理规范形式。
Then action:如果有效,则对表单进行操作。您解释该数据以采取适当的行动。在这里,将其写入数据库。
你的两个步骤在数据的含义上存在分歧。验证从最终数据中删除 award_grant_type_description
和 award_grant_date
,表示 “删除那些字段”。然后,该操作将缺失数据解释为 “保留该字段原样”(这是默认值 ModelForm.save()
所做的)。
您的选择:要么符合 ModelForm
的约定并将字段设置为 None
而不是删除它们,要么覆盖表单的 save()
以便它将缺失数据解释为 “从对象中删除”。除非我有充分的理由改变 ModelForm 的语义,否则我会将字段设置为 None
.
我终于想通了这个问题。
当我用引号括起这些值时,问题就解决了。
这是我使用的有效示例代码:
elif cd_agdf['award_grant_type'] == '8888' or cd_agdf['award_grant_type'] == '9999':
我希望这会对某人有所帮助。
我有一个带有 select 列表的表单。
当用户 select 从 award_grant_type
select 列表中输入 8888 或 9999 的值时,我想要表单输入字段中可能存在或不存在的一些数据(用户可能已经在表单文本输入字段中输入了数据,然后 selected 8888 或 9999)在表单数据提交到数据库之前被删除。
所以我有以下 model.py 代码:
.....
DISPLAY_ONLY_AWARD_AND_GRANT_DESCRIPTION_WITH_PROMPT = 8888
DISPLAY_ONLY_AWARD_AND_GRANT_DESCRIPTION_WITHOUT_PROMPT = 9999
.....
AWARD_GRANT_TYPES = (
(SELECT_AWARD_AND_GRANT_TYPE, _('Select Type')),
(AWARD, _('Award')),
(GRANT, _('Grant')),
(TRAVEL_GRANT, _('Travel Grant')),
(OTHER_AWARD, _('Other Award')),
(OTHER_GRANT, _('Other Grant')),
(WRITE_MY_OWN_AWARD_AND_GRANT_TYPE_DESCRIPTION, _('Write my own Type description')), #7777
(DISPLAY_ONLY_AWARD_AND_GRANT_DESCRIPTION_WITH_PROMPT, _('Display only Description with prompt')), #8888
(DISPLAY_ONLY_AWARD_AND_GRANT_DESCRIPTION_WITHOUT_PROMPT, _('Display only Description without prompt')) #9999
)
user = models.ForeignKey(User)
language_version = models.ForeignKey('LanguageVersion')
award_grant_type = models.PositiveIntegerField(choices=AWARD_GRANT_TYPES, default=SELECT_AWARD_AND_GRANT_TYPE, validators=[MinValueValidator(1)])
award_grant_type_description = models.CharField(null=True, blank=True, max_length=250)
award_grant_date = models.DateField(null=True, blank=True)
award_grant_description = models.TextField(null=False, blank=False, max_length=5000)
这是我的 forms.py 干净代码,当用户从 select 中输入 8888 或 9999 时,应该删除 award_grant_type_description
和 award_grant_date
字段] 在提交到数据库之前列出 award_grant_type
:
def clean(self):
cd_agdf = super(AwardGrantDetailsForm, self).clean()
if 'award_grant_type' in cd_agdf:
if cd_agdf['award_grant_type'] == '':
self._errors['award_grant_type'] = self.error_class([_("You must select a Type.")])
elif cd_agdf['award_grant_type'] == 8888 or cd_agdf['award_grant_type'] == 9999:
# remove the entered values when the award grant type only requires minimum data.
self.cleaned_data.pop('award_grant_type_description', None)
self.cleaned_data.pop('award_grant_date', None)
else:
....
return cd_agdf
任何人都可以指出我做错了什么吗? 在表单数据提交到数据库之前,award_grant_type_description
和 award_grant_date
没有被删除。
编辑/更新
只有在更新现有记录时才会出现此问题。在将表单保存到数据库之前,新记录会根据需要删除数据。当现有记录有一个日期字段作为数据库记录的一部分并且 award_grant_type
从 1 更改为 8888 或 9999 时,award_grant_date
不会从数据库中删除。我想不通为什么。
第二次编辑
我已经发布了一个相关主题
尝试将 self.cleaned_data
更改为 cd_agdf
。字典,那个方法clean
returns,将被用作cleaned_data
。您从 self.cleaned_data
中弹出项目,但返回时未更改 cd_ahdf
。这被描述为 here(请参阅以 "The form's subclass..." 开头的最后一步)。
而不是self.cleaned_data.pop()
在将 cd_agdf
分配给 superclass
cd_agdf.pop()
仅回答编辑:数据的含义存在争议。
表单验证首先发生,其目的是解析提交的数据,清理数据并指出数据中的任何错误。此步骤的结果应该是数据的清理规范形式。
Then action:如果有效,则对表单进行操作。您解释该数据以采取适当的行动。在这里,将其写入数据库。
你的两个步骤在数据的含义上存在分歧。验证从最终数据中删除 award_grant_type_description
和 award_grant_date
,表示 “删除那些字段”。然后,该操作将缺失数据解释为 “保留该字段原样”(这是默认值 ModelForm.save()
所做的)。
您的选择:要么符合 ModelForm
的约定并将字段设置为 None
而不是删除它们,要么覆盖表单的 save()
以便它将缺失数据解释为 “从对象中删除”。除非我有充分的理由改变 ModelForm 的语义,否则我会将字段设置为 None
.
我终于想通了这个问题。
当我用引号括起这些值时,问题就解决了。
这是我使用的有效示例代码:
elif cd_agdf['award_grant_type'] == '8888' or cd_agdf['award_grant_type'] == '9999':
我希望这会对某人有所帮助。