Django中使用反向关系名称(related_name)解决由“多对多”关系引起的字段名字冲突问题引起的迁移命令报错。

news2024/12/24 8:16:31

当在模型中为关系字段添加了related_name参数后,您可以使用该参数指定的名称来引用反向关系。下面是一个简单的例子来说明如何引用反向关系。

假设您有以下两个模型:

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')

在上面的例子中,Book模型有一个外键字段author,它关联到Author模型。通过添加related_name='books'参数,您为Book模型指定了反向关系名称为books

现在,您可以使用该反向关系名称在Author模型的实例中访问与其相关的Book对象集合。例如:

author = Author.objects.get(pk=1)
books = author.books.all()

在上面的代码中,我们从数据库中获取了Author模型的一个实例,并通过books反向关系名称访问了与该作者相关的所有书籍对象。

通过使用related_name参数,您可以根据需要指定反向关系的名称,以便在模型之间进行导航和访问相关对象。

下面是一个“使用反向关系名称(related_name)解决由“多对多”中间关系表的反向关系名引起的冲突问题。

关于什么是中间关系表,为什么要有中间关系表,以及由中间关系表的反向关系名引起的冲突问题的详细解释,请参考我的另一篇表博文:
通过一个实际例子说明Django中的数据库操作方法法ForeignKey()-外键的用法【数据表“一对多”关系】,并详解“中间关系表”、反向关系(related_name)、反向关系名冲突的概念

E:\Python_project\P_001\myshop-test\myshop_background_2\users\models.py 中的代码如下:

from datetime import datetime
from django.db import models
from django.contrib.auth.models import AbstractUser


class MyUser(AbstractUser):
    SEX = (
        (0, '男'),
        (1, '女'),
    )
    LEVEL = (
        (1, '寂寞卡会员'),
        (2, '钻石卡会员'),
        (3, '金卡会员'),
        (4, '银卡会员'),
    )
    STATUS = (
        (0, '正常'),
        (1, '异常'),
    )

    truename = models.CharField('真实姓名', blank=True, max_length=50)
    mobile = models.CharField('手机号码', max_length=11, default="")
    sex = models.IntegerField(default=0, choices=SEX)
    birthday = models.DateField(blank=True, null=True)
    user_img = models.ImageField("头像", upload_to="user_img", default="")
    level = models.IntegerField(default=4, choices=LEVEL)
    status = models.IntegerField(default=0, choices=STATUS)
    create_time = models.DateTimeField(default=datetime.now, verbose_name='创建时间')
    update_time = models.DateTimeField(default=datetime.now, verbose_name="更新时间")

    def __str__(self):
        return self.username

    class Meta(AbstractUser.Meta):
        permissions = (
            ['check_myuser', '审核用户信息'],
        )

执行数据库迁移命令 manage.py makemigrations 时报错如下:

SystemCheckError: System check identified some issues:

ERRORS:
auth.User.groups: (fields.E304) Reverse accessor for 'auth.User.groups' clashes with reverse accessor for 'users.MyUser.groups'.
        HINT: Add or change a related_name argument to the definition for 'auth.User.groups' or 'users.MyUser.groups'.
auth.User.user_permissions: (fields.E304) Reverse accessor for 'auth.User.user_permissions' clashes with reverse accessor for 'users.MyUser.user_permissions'.
        HINT: Add or change a related_name argument to the definition for 'auth.User.user_permissions' or 'users.MyUser.user_permissions'.
users.MyUser.groups: (fields.E304) Reverse accessor for 'users.MyUser.groups' clashes with reverse accessor for 'auth.User.groups'.
        HINT: Add or change a related_name argument to the definition for 'users.MyUser.groups' or 'auth.User.groups'.
users.MyUser.user_permissions: (fields.E304) Reverse accessor for 'users.MyUser.user_permissions' clashes with reverse accessor for 'auth.User.user_permissions'.
        HINT: Add or change a related_name argument to the definition for 'users.MyUser.user_permissions' or 'auth.User.user_permissions'.

错误提示指出了关于groupsuser_permissions字段的冲突。

具体来说,有两个冲突:
①是auth.User的groups字段与users.MyUser中的groups中产生了冲突;
②是auth.User.的user_permissions字段与users.MyUser中的user_permissions产生了冲突。

提问:auth.User是什么时候引入的?
答案在下面这段代码里:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 'basic',
    'users',
]

注意下面代码中的语句:

    'django.contrib.auth',

提问:明明自己的模块中没有定义groupsuser_permissions字段啊?
答:定义了的,因为自己定义的MyUser模型继承自AbstractUser,而AbstractUser又继续了系统自带的User模型的这些字段。

解决方法:

解决方法一:
不在setting.py中去注册应用 ‘django.contrib.auth’,但是如果要使用Django自带的后台系统,不建议这么做,原因如下:
在Django中,默认情况下,django.contrib.auth应用是用于身份验证和用户管理的关键应用程序,它提供了Django自带的后台管理系统的用户认证和权限管理功能。如果您想要使用Django自带的后台管理系统,通常是需要包括django.contrib.auth应用的。

settings.py中的INSTALLED_APPS设置中包括django.contrib.auth应用可以确保后台管理系统正常工作,并具备用户认证和权限管理的功能。这样,您可以使用内置的用户模型、用户组、权限等功能。

如果您不想使用Django自带的后台管理系统,或者您已经有了自定义的用户管理系统,可以考虑从INSTALLED_APPS中移除django.contrib.auth应用。这样可以减少不必要的代码和数据库表,并使得您的项目更加轻量化。

但是请注意,如果您移除了django.contrib.auth应用,您将失去许多与用户认证和权限相关的功能,包括但不限于以下内容:

  • 用户认证和登录功能
  • 用户注册和密码重置功能
  • 用户权限和权限管理功能
  • 用户组管理功能
  • 后台管理系统的用户认证和权限管理功能

所以,在决定是否移除django.contrib.auth应用之前,请确保您已经有了替代的用户认证和权限管理方案,并且考虑到相关功能的实现和维护成本。

解决方法二:

重命名自定义模型中的groupsuser_permissions字段**:如果希望在自定义的模型中保留groupsuser_permissions字段,但避免与内置的auth.User模型发生冲突您可以为这两个字段添加related_name参数并指定不同的名称。例如:

from django.db import models
from django.contrib.auth.models import AbstractUser, Group, Permission


class MyUser(AbstractUser):
	# ...

    groups = models.ManyToManyField(
        Group,
        verbose_name='groups',
        blank=True,
        help_text='The groups this user belongs to.',
        related_name='user_groups'  # 设置不同的 related_name
    )
    user_permissions = models.ManyToManyField(
        Permission,
        verbose_name='user permissions',
        blank=True,
        help_text='Specific permissions for this user.',
        related_name='user_permissions'  # 设置不同的 related_name
    )

    
        # ...

通过为自定义模型中的groupsuser_permissions字段添加related_name参数,并将其设置为与内置auth.User模型的字段不同的名称,可以避免冲突。

请注意,修改模型后,您需要再次运行makemigrationsmigrate命令来应用更改:

python manage.py makemigrations
python manage.py migrate

修改完成后再执行命令 makemigrations ,就没有报错了,如下图所示:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/772426.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ceph 服务的运用

目录 一、资源池 pool 管理 1.创建一个 Pool 资源池 2.查看集群 Pool 信息 3.查看资源池副本的数量 4.查看 PG 和 PGP 数量 5.修改 pg_num 和 pgp_num 的数量为 128 6.修改 Pool 副本数量为 2 7.修改默认副本数为 2 8.删除 Pool 资源池 8.1修改配置文件 8.2推送 ceph…

10.1寸三防加固平板电脑Windows工业平板

当前,移动计算设备的需求日益增长,特别是在现场工作和移动任务中的应用。为了满足这一需求,三防加固平板电脑SP-Q19采用了整机一体成型的设计,无合成拼接,使得长侧边的直线条与短侧边的圆弧形巧妙融合。同时&#xff0…

【wxWidgets】使用布局控件进行窗口布局

使用布局控件进行窗口布局 窗口布局基础 为了在各种环境中都能使窗口拥有合适的位置和大小,可能需要在OnSize事件中计算每一个窗口的大小并设置新位置,当然使用窗口布局控件可以更方便地实现 如果选择使用布局控件,可以通过自己编写或者使用…

创新创业项目申报管理系统vue+nodejs+mysql

开发语言 node.js 框架:Express 前端:Vue.js 数据库:mysql 数据库工具:Navicat 开发软件:VScode 本站是一个B/S模式系统,采用nodejs框架,MYSQL数据库设计开发,充分保证系统的稳定性。系统具有界…

详解UDP协议

在讲本篇文章之前,给读者介绍两个指令 1.netstat:用来查看网络状态的重要工具 语法:netstat [选项] n 拒绝显示别名,能显示数字的全部转化成数字l 仅列出有在 Listen (监听) 的服務状态p 显示建立相关链接的程序名t (tcp)仅显示tcp相关选项…

JDK、JRE、JVM之间的关系是什么?

目录 JVM、JRE、JDK的关系? JDK、JRE、JVM都是什么? JVM JRE JDK JVM、JRE、JDK的关系? 三者包含关系: JDK>JRE>JVM JDK、JRE、JVM都是什么? jdk:是用于java开发的最小环境 包括:ja…

C++牛客WebServer项目学习笔记一

1.Linux系统命令: sudo apt install softname # sudo 管理员权限;apt 安装软件命令;ps -ef | grep ssh # ps 查看进程命令;| 管道符;grep 过滤出(过滤出ssh关键词); 3.Ctrl滚动鼠标…

抓 https 报文新方案 -Magisk+LSPosed,来试试吧

关于如何抓取Android端https报文,在之前一篇文章中有介绍可以通过VitualXposedJustTrustMe模块禁用SSL验证,这样可以抓取到https,还是有一些同学反馈以下的一些问题: App在低版本的Android上不兼容,需要用高版本的And…

leetcode:1470. 重新排列数组(python3解法)

难度:简单 给你一个数组 nums ,数组中有 2n 个元素,按 [x1,x2,...,xn,y1,y2,...,yn] 的格式排列。 请你将数组按 [x1,y1,x2,y2,...,xn,yn] 格式重新排列,返回重排后的数组。 示例 1: 输入:nums [2,5,1,3,4…

SQL-每日一题【607.销售员】

题目 表: SalesPerson 表: Company 表: Orders 编写一个SQL查询,报告没有任何与名为 “RED” 的公司相关的订单的所有销售人员的姓名。 以 任意顺序 返回结果表。 查询结果格式如下所示。 示例: 解题思路 1.我们可以用子查询来解决这道题,…

Tabby - 本地化AI代码自动补全 - Windows10

参考: https://github.com/TabbyML/tabby 安装winget,方便命令行安装git 微软商店,搜索winget,安装App Installer PS C:\Windows\system32> winget install --id Git.Git -e --source winget Found Git [Git.Git] Version 2…

旅游卡加盟代理合伙人模式软件开发

旅游卡加盟代理合伙人模式是近年来逐渐兴起的一种旅游产业发展模式,它通过将旅游卡加盟商与代理商紧密结合,实现资源共享、风险共担、合作共赢的目标。而软件开发作为旅游卡加盟代理合伙人模式的重要技术支持,对于该模式的实施和发展起着至关…

Prometheus节点监控及hadoop集群监控

话不多说,先看效果 1.监控组件Prometheus 1.1上传Prometheus包 [root@bigdb01 ~]# rsync root@172.16.1.247/data/fan/install/native/09.prometheus/jmx_prometheus_javaagent-0.19.0.jar /opt/software/1.2 解压 [root@bigdb01 ~]# mkdir /opt/module/monitoring [roo…

金融银行测试面试题:网上银行转账是怎么测的?

前言 这段时间收到好多粉丝的留言说想求一份金融银行相关的测试面试题,所以我花了不少时间给大家整理了一份,今天分享给需要的朋友们,也希望对你们有所帮助。 1、网上银行转账是怎么测的,设计一下测试用例。 回答思路&#xff1…

【Vue】day02-Vue基础入门

目录 day02 一、今日学习目标 1.指令补充 2.computed计算属性 3.watch侦听器 4.综合案例 (演示) 二、指令修饰符 1.什么是指令修饰符? 2.按键修饰符 3.v-model修饰符 4.事件修饰符 三、v-bind对样式控制的增强-操作class 1.语法…

目标检测数据集标注工具Labelimg安装与使用

一、labelimg是什么 labelimg是一款开源的图像标注工具,标签可用于分类和目标检测,其注释以 PASCAL VOC格式保存为XML文件,这是ImageNet使用的格式。此外,它还支持 COCO数据集格式。 二、安装labelimg 打开cmd并输入以下命令 …

微信小程序导入微信地址

获取用户收货地址。调起用户编辑收货地址原生界面,并在编辑完成后返回用户选择的地址。 1:原生微信小程序接口使用API:wx.chooseAddress(OBJECT) wx.chooseAddress({success (res) {console.log(res.userName)console.log(res.postalCode)c…

【计算机视觉】DINOv2(视觉大模型)代码使用和测试(完整的源代码)

文章目录 一、环境部署二、导入原图2.1 使用vit_s14的模型 三、使用其他模型3.1 使用vit_b14的模型3.2 使用vit_l14的模型3.3 使用vit_g14的模型 一、环境部署 !git clone https://ghproxy.com/https://github.com/facebookresearch/dinov2.git输出为: Cloning in…

OpenCv之图像轮廓(二)

目录 一、多边形逼近 二、凸包 三、最小外接矩形与最大外接矩形 一、多边形逼近 参照函数: approxPolyDP就是以多边形去逼近轮廓,采用的是Douglas-Peucker算法(DP) DP算法原理比较简单,核心就是不断找多边形最远的点加入形成新的多边形,直…

go环境下载github文件显示timeout解决方法

1、问题背景 go环境正常,需要去github拉取一个资源进行编译 go build -v -o naabu cmd/naabu/main.go 编译过程中报错如下: pkg/runner/runner.go:19:2: github.com/miekg/dnsv1.1.53: Get "https://proxy.golang.org/github.com/miekg/dns/v/v1.1.53.zip&q…