在提交到db

时间:2015-06-30 09:19:56

标签: python django python-2.7 django-forms

我有一个带有选择列表的表单。

当用户从award_grant_type选择列表中选择值8888或9999时,我想要一些表格输入字段中可能存在或可能不存在的数据(用户可能已将数据输入表单中文本输入字段,然后选择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清除代码,当用户在提交到db之前从选择列表award_grant_type_description中选择了8888或9999时,应删除award_grant_dateaward_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_descriptionaward_grant_date不会被删除。

编辑/更新

仅在更新现有记录时才会出现此问题。在将表单保存到数据库之前,新记录会根据需要删除数据。当现有记录将日期字段作为db记录的一部分并且award_grant_type从1更改为8888或9999时,则award_grant_date不会从db中删除。我无法弄清楚原因。

第二次编辑

我发布了相关帖子here

4 个答案:

答案 0 :(得分:1)

尝试将self.cleaned_data更改为cd_agdf。字典,该方法clean返回,将用作cleaned_data。您从self.cleaned_data弹出了项目,但未返回cd_ahdf。这是here所描述的(参见以&#34开头的最后一步;表格的子类......")。

答案 1 :(得分:1)

仅回答编辑:对数据的含义存在争议。

首先发生

表单验证,其目的是解析提交的数据,清理它并指出数据中的任何错误。此步骤的结果应该是清理的规范形式的数据。

然后操作:如果有效,则会对表单执行操作。您解释该数据以采取适当的操作。在这里,将其写入数据库。

您的两个步骤不同意数据的含义。验证会从最终数据中删除award_grant_type_descriptionaward_grant_date,以表示“将这些字段删空”。然后,该操作将缺少的数据解释为“保留该字段”(这是默认的ModelForm.save()所做的)。

您的选择:要么符合ModelForm惯例,要么将字段设置为None而不是删除它们,要么覆盖您的表单save(),以便将缺少的数据解释为 “从对象中删除”。除非我有充分的理由改变ModelForm的语义,否则我会将字段设置为None

答案 2 :(得分:1)

我终于想出了这个问题。

当我将值包装在引号中时,问题就解决了。

以下是我使用的示例代码:

 elif cd_agdf['award_grant_type'] == '8888' or cd_agdf['award_grant_type'] == '9999':

我希望这会对某人有所帮助。

答案 3 :(得分:0)

而不是self.cleaned_data.pop() 当您将cd_agdf.pop()分配给cd_agdf

时,请superclass