Django忽略表单中更改的字段

2024-09-26 22:52:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下型号:

class Recipe(models.Model):
    fields...

class Ingredient(models.Model):
    fields...

class UsesIngredient(models.Model):
    recipe = models.ForeignKey(Recipe)
    ingredient = models.ForeignKey(Ingredient)
    amount = models.FloatField()
    group = models.CharField()

我有一个视图,允许用户通过动态表单集为特定配方添加任意数量的“UsesIngredient”模型。组属性将自动填充为对用户隐藏的。在

问题是,当用户在表单集中添加一个新表单,但没有填写任何字段时,我不希望保存该表单。但是,django仍然试图保存表单,因为“group”属性已“更改”(因为在创建额外表单时,它已被自动填充)。在

有什么办法绕过这个问题吗?在

谢谢!在


Tags: 用户表单fieldsmodel属性modelsgrouprecipe
2条回答

您可以通过设置blank=False使所有字段都需要一个值。查看更多here。它应该需要验证您关心的值是否为空。在

如果这不起作用,您可以尝试创建自己的自定义save方法来执行您关心的验证。在

def save(self, *args, **kwargs):
   # Do your checks on the properties such as self.group, self.amount, etc
   # If it is fine then call
   super(UsesIngredient, self).save(*args, **kwargs)

嗯,我对蒂姆·埃德加的解决方案还是不太满意,所以我一直在寻找。我想我找到了我要找的东西。 “Form”类有两个在本例中使用的未记录方法:“has_changed()”和“u get_changed_data”。在

在ModelFormSet验证过程中,每个表单检查“has\u changed()”。如果表单未更改,则跳过验证并假定表单正确。 同样,在保存ModelFormSet期间,save_new_对象会检查每个表单是否已更改。如果没有更改,则不会保存表单。在

因此,我的解决方案是重写has_changed()方法,以便在只有“group”属性发生更改且所有其他字段都为空时返回False。这是我的实现:

class UsesIngredientForm(forms.ModelForm):    
    class Meta:
        model = UsesIngredient

    def has_changed(self, *args, **kwargs):
        self._get_changed_data(*args, **kwargs)
        # If group is in changed_data, but no other fields are filled in, remove group so
        # the form will not be validated or saved
        if 'group' in self._changed_data and len(self._changed_data) == 1:
            contains_data = False
            for name in ['ingredient', 'amount', 'unit']:
                field = self.fields[name]
                prefixed_name = self.add_prefix(name)
                data_value = field.widget.value_from_datadict(self.data, self.files, prefixed_name)
                if data_value:
                    contains_data = True
                    break
            if not contains_data:
                self._changed_data.remove('group')
        return bool(self._changed_data)

希望这对将来的任何人都有帮助!在

编辑: 我编辑这个答案是为了反映蒂姆·埃德加的评论。 我意识到这个实现仍然使用“private”方法,但是我还没有找到一个更干净的实现,只使用公开文档化的方法。但也许那只是我自己的无能。在

相关问题 更多 >

    热门问题