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

Django中FOREIGN KEY约束失败,如何修改用户数据更新逻辑?

解决Django更新用户数据时的FOREIGN KEY约束失败问题

我尝试通过Web请求更新用户数据,未使用forms.py,执行过程中触发了FOREIGN KEY constraint failed错误。以下是我的代码:

models.py

from ast import Delete
from email.policy import default
from django.db import models
from django.contrib.auth.models import User


class Euser(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    phone = models.CharField(max_length=10,null=True)
    birthdate = models.DateField(null=True,)
    profile_pic = models.ImageField(null=True, )
    cover_pic = models.ImageField( null=True, upload_to="images/%y")

    def __str__(self):
        return self.phone

views.py

def editprofile(request, pk):
    return render(request, 'proedit.html')

def submitedit(request):
    if request.method=="POST":

        current_user = request.user.id
        firstname = request.POST.get('firstname') 
        lastname = request.POST.get('lastname')
        username = request.POST.get('username')
        email = request.POST.get('email')
        phone = request.POST.get('mobileno')
        birthdate = request.POST.get('birthdate')
        profile_pic = request.FILES['profile_pic']

       
        print(current_user)
        User.objects.filter(pk=current_user).update(username=username,first_name=firstname,last_name=lastname,email=email)
      
        Euser.objects.filter(pk=current_user).update_or_create(
        phone=phone,birthdate=birthdate,profile_pic=profile_pic,
        defaults={'phone': phone,'birthdate': birthdate,'profile_pic': profile_pic},)

问题原因

你犯了两个关键错误:

  1. 用User的ID去过滤Euser的主键(pk=current_user),但Euser的主键是自身的自增ID,和User的ID完全无关,根本查不到对应的数据。
  2. 调用update_or_create时,没有指定关联的User实例作为外键条件,导致创建新Euser时缺少user外键值,触发数据库外键约束错误。

修改方案

直接修改submitedit函数,逻辑调整如下:

def submitedit(request):
    if request.method == "POST":
        # 直接获取当前登录的User实例,不用只拿ID
        current_user = request.user
        
        # 获取表单数据
        firstname = request.POST.get('firstname') 
        lastname = request.POST.get('lastname')
        username = request.POST.get('username')
        email = request.POST.get('email')
        phone = request.POST.get('mobileno')
        birthdate = request.POST.get('birthdate')
        # 用get方法避免用户没上传头像时触发KeyError
        profile_pic = request.FILES.get('profile_pic')

        # 更新User表数据
        User.objects.filter(pk=current_user.pk).update(
            username=username,
            first_name=firstname,
            last_name=lastname,
            email=email
        )
      
        # 基于user外键查询Euser,不存在则创建,存在则更新
        Euser.objects.update_or_create(
            # 必须把关联的User实例作为查询条件
            user=current_user,
            defaults={
                'phone': phone,
                'birthdate': birthdate,
                # 只有当用户上传了新头像才更新,避免覆盖原有数据
                **({'profile_pic': profile_pic} if profile_pic else {})
            }
        )
        # 记得加个重定向,避免表单重复提交
        return redirect('editprofile', pk=current_user.pk)

额外注意事项

  • 如果profile_pic不是必填项,一定要用request.FILES.get('profile_pic'),而不是直接取request.FILES['profile_pic'],否则用户没上传头像时会抛出KeyError。
  • 确保前端传的birthdate格式是Django能解析的(比如YYYY-MM-DD),否则日期字段会更新失败。
  • 处理完表单后记得重定向到编辑页面,避免用户刷新页面重复提交表单。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 05:27:28