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 中的外键关系被正确处理,避免数据一致性和完整性问题。

相关推荐
uoKent几秒前
MySQL常见命令梳理大纲
数据库·mysql
晚霞的不甘12 分钟前
Flutter for OpenHarmony专注与习惯的完美融合: 打造你的高效生活助手
前端·数据库·经验分享·flutter·前端框架·生活
2301_7657031414 分钟前
工具、测试与部署
jvm·数据库·python
山岚的运维笔记20 分钟前
SQL Server笔记 -- 第13章:IF...ELSE
数据库·笔记·sql·microsoft·sqlserver
创客小邓26 分钟前
Qt对SQLite数据库的操作
数据库·qt·sqlite
中二病码农不会遇见C++学姐39 分钟前
《文明6》Mod开发实战:从游戏日志定位和解决Mod加载问题
数据库·游戏·oracle
naruto_lnq1 小时前
Python日志记录(Logging)最佳实践
jvm·数据库·python
酉鬼女又兒1 小时前
SQL23 统计每个学校各难度的用户平均刷题数
数据库·sql·算法
bigdata-rookie1 小时前
Starrocks 简介
大数据·数据库·数据仓库
2301_765703141 小时前
Python异步编程入门:Asyncio库的使用
jvm·数据库·python