更正绑定的ModelFormSet上的空值

时间:2012-03-31 12:36:38

标签: django django-forms

我有一个应用来管理一些人的图书订单,这是模型:

class Order(models.Model):
    person = models.ForeignKey(Person)
    book = models.ForeignKey(Book)
    qty = models.IntegerField(default=0)

我还使用ModelFormSet来允许人们一次订购几本书。虽然表单使用“qty”字段的初始0值,但我担心有些人会使用空字符串而不是它。 所以,我想要的是在处理表单之前将这个Null条目“转换”为0(但是在它被绑定之后,很明显) 我找到了以下解决方案:

def order(request, person_id):
    if request.method == "POST":
        # Hack to correct Null entries from user... TODO: find better way...
        posted_datas = request.POST.copy()
        for p in [k for k,v in posted_datas.items() if re.compile("qty").search(k) and not v]:
            posted_datas[p] = 0
        formset = BookOrderFormSet(posted_datas)
        if formset.is_valid():
....

它工作正常,我觉得它可能会帮助处于相同情况的人,但我想知道是否有更好/更清洁的方式...

1 个答案:

答案 0 :(得分:2)

修改 因此,您希望原谅删除默认值为0的用户并将qty字段保留为空,而不提供任何合适的数字,方法是将字段值重置为0,以显示错误“qty is required”?通常,最好不要这样做IMHO =)

但是如果你想要,除了在视图中检查并设置它之外,你还可以修补表单Field的clean方法,以便不为空值引发异常,而是将其更改为默认值。例如

from django.core.validators import EMPTY_VALUES

class SmoothIntegerField(IntegerField):
    def clean(self, value):
        if value in EMPTY_VALUES:
            value = self.initial # set to default value
        return super(SmoothIntegerField, self).clean(value)    

忽略以下的误解答案

我认为你不需要额外的工作。 Django表单和模型很好地保护它:

  • 空字符串''或完全没有数量将不会被传递,因为需要数量字段
  • 非整数的字符串将不会被传递,因为IntegerField本身确保将非空值强制转换为整数
  • 即使你不使用formset.is_valid来确保上面的东西,非数字如null仍然不能在DB中,因为存在qty列不可为空的限制