ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python-为什么Django给我这个“违反非空约束”错误?

2019-11-02 14:58:02  阅读:232  来源: 互联网

标签:django-forms python django django-models


错误:

null value in column “postal_code_id” violates not-null constraint

表格:

def add(request):
    if request.method == 'POST':
        address_form = AddressForm(request.POST)
        company_form = CompanyForm(request.POST)
        if address_form.is_valid() and company_form.is_valid():
            print address_form.cleaned_data['postal_code'] # <-- prints (<PostalCode: V4N 1K6>, False)
            address_form.save() # <------------------------------- occurs here
        else:
            print 'Address errors',address_form.errors
            print 'Company errors', company_form.errors
    else:
        address_form = AddressForm()
        company_form = CompanyForm()
    return render(request, 'company/add.html', locals())

显然,表单确实具有有效的PostalCode对象,因此我不确定为什么要说它违反了非null约束.当然,我对表单做了一些有趣的事情:

class AddressForm(ModelForm):
    postal_code = CharField(max_length=10, validators=[validate_postal_code])
    city = CharField(max_length=50, validators=[validate_non_whitespace])
    province = CharField(max_length=50, validators=[validate_non_whitespace])
    country = CharField(max_length=50, initial='Canada', validators=[validate_non_whitespace])

    def clean_postal_code(self):
        code = self.cleaned_data['postal_code']
        code = code.upper()
        code = re.sub('[^A-Z0-9]', '', code)
        code = code[:3] + ' ' + code[-3:]
        return code

    def clean_country(self):
        country = self.cleaned_data['country']

        try:
            country = Country.objects.get(name__iexact=country)
        except Country.DoesNotExist:
            raise ValidationError('Country does not exist')

        return country

    def clean_province(self):
        province = self.cleaned_data['province']

        if not Province.objects.filter(name__iexact=province).exists():
            raise ValidationError('Province does not exist')

        return province

    def clean(self):
        data = self.cleaned_data

        if 'country' in data and 'province' in data:
            try:
                data['province'] = Province.objects.get(country=data['country'], name__iexact=data['province'])
                if 'city' in data:
                    data['city'] = City.objects.get_or_create(name__iexact=data['city'], province=data['province'], defaults={'name':data['city']})[0]
                    if 'postal_code' in data:
                        data['postal_code'] = PostalCode.objects.get_or_create(code=data['postal_code'], city=data['city'])
            except Province.DoesNotExist:
                self._errors['province'] = self.error_class(['Province does not exist in that Country'])
                del data['province']

        return data

    class Meta:
        exclude = ['postal_code']
        model = Address

具体来说,我将用文本字段替换postal_code字段,然后在“ clean”方法中查找/创建对象.为什么这会混淆Django?它最终获得了所需的对象,不是吗?

解决方法:

您将排除postal_code,这将导致模型表单稍后在尝试保存期间跳过字段.我遇到了类似的问题,不得不跟踪django代码以找出行为.值得一提.

您要做的是设置用于postal_code字段的小部件,而不是排除然后包括.

class AddressForm(ModelForm):
    class Meta:
        model = Address
        widgets = {
            'postal_code': CharField(max_length=10),
        }

那应该允许模型表单正确验证字段并保存它.为了简洁起见,我将其余表格排除在外.

编辑:

试图将CharField用作ForeignKey在ModelForm中充满了恐惧.而是将其转换为常规形式.无论如何,您似乎已经在定义大多数字段.然后依靠您来验证字段是否有效,并且已经是数据库的成员.创建一个行为类似于ModelForm save方法的保存方法,然后就可以使用.

标签:django-forms,python,django,django-models
来源: https://codeday.me/bug/20191102/1992127.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有