【问题标题】:Django IntegrityError; NOT NULL constraint failedDjango 完整性错误; NOT NULL 约束失败
【发布时间】:2015-05-20 07:25:17
【问题描述】:

我正在尝试保存模型的实例但无济于事。

下面是我的模型;

class AudioFile(models.Model):
    name = models.CharField(max_length=100,default='')
    audio_file = models.FileField()
    uploader = models.ForeignKey(User,default='')

    def __unicode__(self):
        return self.name    

我有以下表格;

class AudioFileForm(forms.ModelForm):
    class Meta:
        model = AudioFile
        fields = ['name', 'audio_file']

    def clean_audio_file(self):
        audio = self.cleaned_data['audio_file']
        if audio:
            if audio._size > 5*1024*1024:
                raise ValidationError("File too large ( > 5mb )")
            if os.path.splitext(audio.name)[1] != ".mp3":
                raise ValidationError("We only support mp3!")
            return audio
        else:
            raise validationError("Couldn't read uploaded file")

我有以下视图来处理提交的表单;

form = AudioFileForm(request.POST, request.FILES)
    if form.is_valid():
        form.cleaned_data['uploader'] = request.user //view requires login
        form.save()
        return HttpResponseRedirect(
            reverse('home_audio',kwargs={'pk':audio_file.pk})
            )
    else:
        return HttpResponse(form.errors)

但是在提交时我得到了错误; IntegrityError at /uploadaudio NOT NULL constraint failed: stationrunner_audiofile.uploader_id /uploadaudio 是与视图对应的 URL,stationrunner 是我的应用名称。

请有人帮忙。

【问题讨论】:

    标签: django


    【解决方案1】:

    尝试改变视图:

    form = AudioFileForm(request.POST, request.FILES)
    if form.is_valid():
        audio_file = form.save(commit=False) // This will not hit the database, and no IntegrityError will be raised
        audio_file.uploader = request.user  // Tack on the user, 
        audio_file.save()
        return HttpResponseRedirect(
            reverse_lazy('home_audio',kwargs={'pk':audio_file.pk}) // Use reverse lazy to prevent circular import issues.
        )
    else:
        return HttpResponse(form.errors)
    

    您还可以修复模型的一些问题:

    from django.conf import settings
    from django.db import models
    
    class AudioFile(models.Model):
        name = models.CharField(max_length=100) // If the field is not allowed to be blank, the default blank does not make sense.
        audio_file = models.FileField(upload_to="audio_files") // Without this parameter file field does not work.
        uploader = models.ForeignKey(settings.AUTH_USER_MODEL) // This should reference the user model declared in your settings file.
    
        def __unicode__(self):
            return self.name   
    

    【讨论】:

    • Thanx man 按照您的建议更改视图就成功了。但我想知道uploader = models.ForeignKey(User, default'') 与您建议的有何不同。还有upload_to="some/location" is no more required,Django 1.7 以上。告诉我这件事的人说他认为这是一种很好的做法。
    • 默认设置的空字符串无效,因为外键用整数表示,只会造成混淆。此外,设置授权用户应始终引用用户模型,以使应用程序更具可重用性。如果您想在将来重用它,或者让其他人重用它,他们将不必更换用户模型。感谢您让我知道不再需要 upload_to。
    • 如果我需要与自定义模型建立关系怎么办?那我需要models.ForeignKey(ModelName, default='') 对吧?
    • 如果您的意思是自定义用户模型,那么没有。我发布的代码可以正常工作。 default="" 设置对我来说毫无意义,因为外键不能是空字符串。
    • 简单的定制模型,任何模型。我只是在学习 Django。我不记得确切的消息,但是在ForeignKey 关系上没有default='',我被要求在尝试执行makemigrations 时提供默认值,因此default=''
    猜你喜欢
    • 1970-01-01
    • 2021-06-10
    • 2015-08-10
    • 1970-01-01
    • 1970-01-01
    • 2023-02-20
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    相关资源
    最近更新 更多