解决django报错:IntegrityError: NOT NULL constraint failed: learning_logs_topic.owner_id

博主采用(2)(4)步骤解决


最近在学习《python 从入门到实战》第19章,在learning_logs中models 添加了topic的用户属性,即哪个用户登录后创建的topic,则此topic的owner属性为此登录用户,代码:owner=models.ForeignKey(User,on_delete=models.CASCADE),owner 是User的外键(pthon 版本3.7.4,django版本2.2.6 ),并且在makemigrations后出现了如下提示:

此时选择是‘1)’的选项,然后选择的用户ID为1,即ll_admin,此时即原有topic的归属用户ID为1,即ll_admin,在执行new_topic时出现了如下错误:

IntegrityError at /new_topic/ NOT NULL constraint failed: learning_logs_topic.owner_id,错误现场如下:

其中topic 的model 源码如下:

class Topic(models.Model) :
    text=models.CharField(max_length=200)
    date_added=models.DateTimeField(auto_now_add=True)
    owner=models.ForeignKey(User,on_delete=models.CASCADE)    
    def __str__(self) :
        return self.text

topicform的源码如下:

class TopicForm(forms.ModelForm):
    class Meta :
        model=Topic 
        fields =['text']
        labels={'text' : ''}

learning_logs 文件夹下views.py 的new_topic 源码如下:

def new_topic(request) :
    if request.method != 'POST' :
        form=TopicForm()
        
    else :
        form= TopicForm(request.POST)
        if form.is_valid() :
            form.save()
            return HttpResponseRedirect(reverse('learning_logs:topics'))
            
    context={'form':form}
    return render(request,'learning_logs/new_topic.html',context)

此错误显示空值限制错误:owner,owner是models里面刚添加的属性,虽然在已存在的topic添加了owner 属性,但新添加的topic没有owner属性,所以报错。

解决的过程如下:

(1)在models.py 属性添加null=True,即允许此属性为空

修改后变为owner=models.ForeignKey(User,on_delete=models.CASCADE,null=True),修改后错误不再出现,但新添加的topic的owner为NULL,非设计所愿

(2)在models.py 里面添加默认值。

修改后owner=models.ForeignKey(User,on_delete=models.CASCADE,default=1),修改后错误也不再出现,但新添加的topic的owner均为ID为1的用户,也非设计所愿

(3)修改TopicForm,添加owner 字段

修改后TopicForm 变为如下:

class TopicForm(forms.ModelForm):
    class Meta :
        model=Topic 
        fields =['text,‘owner’']
        labels={'text' : '','owner':''}

修改后将由用户选择此新建topic 的owner,如下所示:

虽然可以选择当前登录用户为此topic的owner ,但用户也可以选择其它非当前登录用户,增加了出现错误的风险

(4)在views.py new_topic视图里,用request.user 获取当前用户,并赋值给form

即在if form.is_valid() :后添加一行:

form.instance.owner=request.user,修改后变为:

def new_topic(request) :
    if request.method != 'POST' :
        form=TopicForm()
        
    else :
        form= TopicForm(request.POST)
        if form.is_valid() :
           form.instance.owner=request.user
            form.save()
            return HttpResponseRedirect(reverse('learning_logs:topics'))
            
    context={'form':form}
    return render(request,'learning_logs/new_topic.html',context)

即用Form的instance 参数,来获取owner 属性,并用requset.user得到的当前用户赋值给此instance的owner。修改后程序实现预定功能

(5)也是利用了instance参数,不过是在生成的Form的时候,修改后new_topic的视图如下:

def new_topic(request) :
    if request.method != 'POST' :
        form=TopicForm()
        
    else :
        form= TopicForm(request.POST)
        topic=Topic()
        topic.owner=request.user
        form= TopicForm(request.POST,instance=topic)
        if form.is_valid() :
            form.save()
            return HttpResponseRedirect(reverse('learning_logs:topics'))
            
    context={'form':form}
    return render(request,'learning_logs/new_topic.html',context)

先生成一个topic,然后赋值给owner,再将此topic赋值给instance参数,空间、时间成本较大,不过也实现了预定的功能。


该文章转载自:点击转到原地址

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值