我在其中一个模型中有三个整数字段,如下所示:
class SomeModel(models.Model):
min_age = models.IntegerField()
max_age = models.IntegerField()
savings = helpers.MoneyField()
MoneyField 是一个自定义字段,它使用一个小部件将金额(170000)分解为两个下拉列表,分别为 100000(十万)和(70000)千。
对于我使用上述货币字段的表单,我有一个form preview
视图,它强制用户在发布之前预览表单。
使用相同的想法,我想更改min_age
并max_age
使用单个小部件。所以我,
添加了一个 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
方法将值插入到实际模型字段中一样。
这就是发生的事情。
- 用户填写表格并单击“预览”。
security_hash
这将为该特定表单创建一个并呈现预览视图。- 如果表单没问题,用户再次提交表单,否则他单击编辑按钮再次编辑表单。
现在,如果表单没问题,并且用户单击提交按钮,表单预览而不是提交表单会循环回预览。然后在预览模板上再次单击提交按钮时,表单将被提交。
这很可能是因为我们在生成 security_hash 之后在上面的 full_clean 方法中设置了min_age
和的值。max_age
上面的方法在我们操作数据时会改变 security_hash。
第二次,用户提交表单。min_age
和max_age
字段已经有相同的数据,所以security_hash
保持不变。
有什么方法可以操纵 security_hash,或者可以在生成 security_hash 之前将值插入 min_age 和 max_age。让它保持不变?
实现上述目标的最佳方法是什么?
欢迎任何建议。谢谢。
更新:
我试图更深入地挖掘,因为我假设安全哈希失败了。因此,为了确保我在调用视图failed_hash()
之前重写了打印错误消息的方法,并猜测这是被调用的方法并将表单重定向回方法。preview_post()
FormPreview
preview_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()
方法仍在被调用,循环仍然存在。:(