Django外键模型未保存引用

在 Django 中使用外键关系时,如果遇到模型未保存引用的问题,通常是因为在创建或更新相关对象时,有关联对象未被正确保存或引用。这里提供一些常见的问题和解决方案来确保你的外键关系正确处理。

1、问题背景

在使用 Django 进行模型开发时,遇到一个问题,外键模型无法保存引用。具体来说,UserProfile 模型的外键引用 Customer 模型,在保存 UserProfile 模型时,引用关系丢失。

代码如下:

python 复制代码
from django.db import models
from customers.models import Customer
from django.contrib.auth.models import User, Group
from django.contrib.sites.models import Site
from anfitrion.models import ModelBase
from django.db.models.signals import post_save

class UserProfile(ModelBase):
    user = models.OneToOneField(User)
    customer = models.ForeignKey(Customer)
    address = models.CharField(max_length = 255)
    phone_home = models.CharField(max_length = 16)
    phone_office = models.CharField(max_length = 16)
    expiration = models.DateTimeField(null=True, blank=True)
    picture = models.ImageField(upload_to='profiles/%Y/%m/%d')
    observations = models.TextField(null=True, blank=True)
    status = models.BooleanField()

    def __str__(self):
        return "%s's profile" % self.user  

def create_user_profile(sender, instance, created, **kwargs):
    if created:
        profile, created = UserProfile.objects.get_or_create(user=instance)  

post_save.connect(create_user_profile, sender=User)

class SiteProfile(ModelBase):
    site = models.OneToOneField(Site)

    def __str__(self):
        return "%s's profile" % self.user  

def create_site_profile(sender, instance, created, **kwargs):
    if created:
        profile, created = SiteProfile.objects.get_or_create(site=instance)  

post_save.connect(create_site_profile, sender=Site)

function running the saveing
def users_save (request):
    #try:
        if request.is_ajax() and request.POST:
            user_id = request.POST['user_id']
            s = get_current_site(request)
            u = User (
                      username = request.POST['username'],
                      first_name = request.POST['first_name'],
                      last_name = request.POST['last_name'],
                      email = request.POST['email']
                      )
            u.set_password(request.POST['password'])
            c = None
            if int( request.POST['customer_id'] ) > 0: 
                c = Customer.objects.get(id=request.POST['customer_id'])
            up = UserProfile(
                      customer = c,
                      address = request.POST['address'],
                      phone_home = request.POST['phone_home'],
                      phone_office = request.POST['phone_office']
                      )
            up.user = u
            u.save()
            if int( request.POST['group_id'] ) > 0:
                g = Group.objects.get( id = request.POST['group_id'] )
                g.user_set.add(u)
            return HttpResponse(1, mimetype='application/json')

2、解决方案

经过分析,发现问题出在保存模型的方式上。在代码中,先保存了用户模型 u,然后再将 u 设置为 UserProfile 模型的 user 属性,最后才保存 UserProfile 模型。这种方式会导致外键引用丢失,因为在保存 UserProfile 模型时,u 还没有被保存,因此引用关系无法建立。

正确的做法是先保存 UserProfile 模型,然后再保存用户模型 u。这样,外键引用就可以正常建立。

python 复制代码
up = UserProfile(
                      customer = c,
                      address = request.POST['address'],
                      phone_home = request.POST['phone_home'],
                      phone_office = request.POST['phone_office']
                      )
up.save()
up.user = u
u.save()

修改后的代码如下:

python 复制代码
from django.db import models
from customers.models import Customer
from django.contrib.auth.models import User, Group
from django.contrib.sites.models import Site
from anfitrion.models import ModelBase
from django.db.models.signals import post_save

class UserProfile(ModelBase):
    user = models.OneToOneField(User)
    customer = models.ForeignKey(Customer)
    address = models.CharField(max_length = 255)
    phone_home = models.CharField(max_length = 16)
    phone_office = models.CharField(max_length = 16)
    expiration = models.DateTimeField(null=True, blank=True)
    picture = models.ImageField(upload_to='profiles/%Y/%m/%d')
    observations = models.TextField(null=True, blank=True)
    status = models.BooleanField()

    def __str__(self):
        return "%s's profile" % self.user  

def create_user_profile(sender, instance, created, **kwargs):
    if created:
        profile, created = UserProfile.objects.get_or_create(user=instance)  

post_save.connect(create_user_profile, sender=User)

class SiteProfile(ModelBase):
    site = models.OneToOneField(Site)

    def __str__(self):
        return "%s's profile" % self.user  

def create_site_profile(sender, instance, created, **kwargs):
    if created:
        profile, created = SiteProfile.objects.get_or_create(site=instance)  

post_save.connect(create_site_profile, sender=Site)

function running the saveing
def users_save (request):
    #try:
        if request.is_ajax() and request.POST:
            user_id = request.POST['user_id']
            s = get_current_site(request)
            u = User (
                      username = request.POST['username'],
                      first_name = request.POST['first_name'],
                      last_name = request.POST['last_name'],
                      email = request.POST['email']
                      )
            u.set_password(request.POST['password'])
            c = None
            if int( request.POST['customer_id'] ) > 0: 
                c = Customer.objects.get(id=request.POST['customer_id'])
            up = UserProfile(
                      customer = c,
                      address = request.POST['address'],
                      phone_home = request.POST['phone_home'],
                      phone_office = request.POST['phone_office']
                      )
            up.save()
            up.user = u
            u.save()
            if int( request.POST['group_id'] ) > 0:
                g = Group.objects.get( id = request.POST['group_id'] )
                g.user_set.add(u)
            return HttpResponse(1, mimetype='application/json')

通过修改代码,成功解决了 Django 外键模型无法保存引用的问题。

通过注意这些常见问题和采取正确的操作步骤,可以确保 Django 中的外键关系被正确处理,避免数据一致性和完整性问题。

相关推荐
Lw老王要学习15 分钟前
Linux数据库篇、第一章_02_MySQL的使用增删改查
linux·运维·数据库·mysql·云计算·it
林下清风~19 分钟前
MySQL——九、锁
数据库·mysql
呦呦鹿鸣Rzh1 小时前
redis
数据库·redis·缓存
xiaogai_gai1 小时前
有效的聚水潭数据集成到MySQL案例
android·数据库·mysql
web130933203982 小时前
Mysql的安装配置教程(非常详细)从零基础入门到精通,看完这一篇就够了
数据库·mysql
三天不学习2 小时前
浅析AI大模型为何需要向量数据库?【入门基础】
数据库·人工智能·欧氏距离·向量数据库·余弦相似度
MonkeyKing_sunyuhua2 小时前
将数据库结构化数据整合到RAG问答中的方式
数据库
喝醉酒的小白2 小时前
MySQL内存使用率高问题排查与解决方案:
数据库
鹅鹅鹅呢2 小时前
mysql 登录报错:ERROR 1045(28000):Access denied for user ‘root‘@‘localhost‘ (using password Yes)
android·数据库·mysql
摘星编程2 小时前
Redis+Caffeine构建高性能二级缓存
数据库·redis·缓存