1

我在其中一个模型中有三个整数字段,如下所示:

class SomeModel(models.Model):
    min_age = models.IntegerField()
    max_age = models.IntegerField()
    savings = helpers.MoneyField()

MoneyField 是一个自定义字段,它使用一个小部件将金额(170000)分解为两个下拉列表,分别为 100000(十万)和(70000)千。

对于我使用上述货币字段的表单,我有一个form preview视图,它强制用户在发布之前预览表单。

使用相同的想法,我想更改min_agemax_age使用单个小部件。所以我,

  1. 添加了一个 AgeFields(多值字段如下):

    类 AgeField(forms.MultiValueField):

    def __init__(self, *args, **kwargs):
        """ 
        Have to pass a list of field types to the constructor, else we
        won't get any data to our compress method.
        """
    
        all_fields = ( 
            forms.CharField(),
            forms.CharField(),
            )   
        super(AgeField, self).__init__(all_fields, *args, **kwargs)
    
    def compress(self, values):
        if values:
            print values
            return '|'.join(values)
        return ''
    

然后在表单中,我隐藏了模型字段并使用上面的字段来使用看起来类似于MoneyWidget()

class PostForm(forms.ModelForm):
    age = AgeField(widget=widgets.AgeWidget(),
            required=False)

    def is_valid(self):
        return super(PostForm, self).is_valid()

    def full_clean(self, *args, **kwargs):
        print self.data
        if 'age_0' in self.data:
            newdata = self.data.copy()
            newdata['min_age'] = self.data['age_0']
            newdata['max_age'] = self.data['age_1']
            print newdata
            self.data = newdata
        super(PostForm, self).full_clean(*args, **kwargs)

    class Meta:
        model = models.SomeModel
        fields = (
                  'age', 'min_age', 'max_age',
                  'savings'
                 )
        widgets = {
            'min_age' : forms.HiddenInput(),
            'max_age' : forms.HiddenInput(),
            'savings' : widgets.MoneyWidget(),
        }

目前一切正常,尽管FormPreview创建了一个循环。正如我使用上述full_clean方法将值插入到实际模型字段中一样。

这就是发生的事情。

  1. 用户填写表格并单击“预览”。
  2. security_hash这将为该特定表单创建一个并呈现预览视图。
  3. 如果表单没问题,用户再次提交表单,否则他单击编辑按钮再次编辑表单。

现在,如果表单没问题,并且用户单击提交按钮,表单预览而不是提交表单会循环回预览。然后在预览模板上再次单击提交按钮时,表单将被提交。

这很可能是因为我们在生成 security_hash 之后在上面的 full_clean 方法中设置了min_age和的值。max_age上面的方法在我们操作数据时会改变 security_hash。

第二次,用户提交表单。min_agemax_age字段已经有相同的数据,所以security_hash保持不变。

有什么方法可以操纵 security_hash,或者可以在生成 security_hash 之前将值插入 min_age 和 max_age。让它保持不变?

实现上述目标的最佳方法是什么?

欢迎任何建议。谢谢。

更新:

我试图更深入地挖掘,因为我假设安全哈希失败了。因此,为了确保我在调用视图failed_hash()之前重写了打印错误消息的方法,并猜测这是被调用的方法并将表单重定向回方法。preview_post()FormPreviewpreview_post()

我认为安全哈希无法匹配,因为我POST在上述full_clean()方法中操作数据,所以我设置了 min_age 和 max_age required=False,然后尝试显式设置save()方法中的值,如下所示

def save(self, *args, **kwargs):
    if 'age_0' in self.data:
        newdata = self.data.copy()
        newdata['min_age'] = self.data['age_0']
        newdata['max_age'] = self.data['age_1']
        self.data = newdata
    super(PostForm, self).save(*args, **kwargs)

def __init__(self, *args, **kwargs):
    super(PostForm, self).__init__(*args, **kwargs)
    for key in self.fields:
        self.fields['min_age'].required = False
        self.fields['max_age'].required = False

但仍然没有运气。该failed_hash()方法仍在被调用,循环仍然存在。:(

4

0 回答 0