You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django POST请求报错IntegrityError:NOT NULL约束失败(author_id)

问题:Django自定义界面POST请求失败,提示author_id非空约束错误

我用Python和Django搭建数据库驱动网站,自定义index界面无法完成POST请求,但Django admin界面操作正常。提交时抛出错误:

django.db.utils.IntegrityError: NOT NULL constraint failed: mylist_item.author_id

我在models.py里定义了关联User外键的Item类,但不知道怎么在views.py里设置并传递author_id。以下是我的代码:

views.py

from django.shortcuts import render
from .models import Item
from django.db.models import Q
from django.contrib.auth.decorators import login_required
from django.views.generic import ListView, DetailView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.edit import CreateView


# Create your views here.

def mylist(request):
    if request.method == 'POST':
        Item.objects.create(name = request.POST['itemName'],
        beschreibung = request.POST['itemBeschreibung'],
        link = request.POST['itemTag'],
        public = request.POST['itemPublic'],
        useridnummer = request.POST['itemUserid'],)
        post = request.save(commit=False)
        post.author = request.user

    all_items = Item.objects.all()

    if 'q' in request.GET:
        q = request.GET['q']
        # all_items = Item.objects.filter(name__icontains=q)
        multiple_q = Q(Q(name__icontains=q) | Q(beschreibung__icontains=q) | Q(link__icontains=q))
        all_items = Item.objects.filter(multiple_q)


    return render(request, 'index.html', {'all_items': all_items})


@login_required(login_url='user-login')
def private(request):
    all_items = Item.objects.all()
    return render(request, 'private.html', {'all_items': all_items})

models.py

from django.db import models
from django.conf import settings
from datetime import date
from django.contrib.auth import get_user_model

# Create your models here.

User = get_user_model()

class Item(models.Model):
    created_at = models.DateField(default=date.today)
    name = models.CharField(max_length=200)
    beschreibung = models.TextField(max_length=10000, default="")
    link = models.CharField(max_length=200, default="")
    public = models.CharField(max_length=200, default="")
    useridnummer = models.CharField(max_length=200, default="")
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    

    def __str__(self):
        #return self.title + ' | ' + self.author
        return str(self.id) + ' ' + self.name + ' | ' + str(self.author)

解决方案

你的问题核心是POST处理逻辑错误:

  1. 直接用Item.objects.create()创建对象时,没有传入author参数,触发了数据库非空约束。
  2. 后面的request.save(commit=False)是错误写法,request对象没有save方法,这行代码既无效也没起到设置author的作用。

修改mylist视图的POST部分,两种正确写法可选:

写法一:创建时直接传入author

def mylist(request):
    if request.method == 'POST':
        # 先校验用户是否登录,避免匿名用户提交
        if request.user.is_authenticated:
            Item.objects.create(
                name=request.POST['itemName'],
                beschreibung=request.POST['itemBeschreibung'],
                link=request.POST['itemTag'],
                public=request.POST['itemPublic'],
                useridnummer=request.POST['itemUserid'],
                author=request.user  # 关联当前登录用户
            )

    # 剩余查询逻辑不变
    all_items = Item.objects.all()
    if 'q' in request.GET:
        q = request.GET['q']
        multiple_q = Q(Q(name__icontains=q) | Q(beschreibung__icontains=q) | Q(link__icontains=q))
        all_items = Item.objects.filter(multiple_q)

    return render(request, 'index.html', {'all_items': all_items})

写法二:先实例化对象,设置author后再保存

def mylist(request):
    if request.method == 'POST':
        if request.user.is_authenticated:
            item = Item(
                name=request.POST['itemName'],
                beschreibung=request.POST['itemBeschreibung'],
                link=request.POST['itemTag'],
                public=request.POST['itemPublic'],
                useridnummer=request.POST['itemUserid'],
            )
            item.author = request.user
            item.save()

    # 剩余查询逻辑不变
    all_items = Item.objects.all()
    if 'q' in request.GET:
        q = request.GET['q']
        multiple_q = Q(Q(name__icontains=q) | Q(beschreibung__icontains=q) | Q(link__icontains=q))
        all_items = Item.objects.filter(multiple_q)

    return render(request, 'index.html', {'all_items': all_items})

额外建议:

  • 给mylist视图加上@login_required装饰器,强制用户登录后才能提交数据,避免匿名用户触发错误。
  • 推荐使用Django表单类处理提交数据,替代直接读取request.POST,能自动完成字段验证和错误处理。

内容的提问来源于stack exchange,提问作者b0sna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 12:45:38