Django大坑之外键设置外键冲突

用Django开发了一个在线教育网站,众所周知,Django是一个开发后端的一个强大框架,用了它就不用管MySQL里面的增删改查,直接在PyCharm里迁移搞定。
想在课程机构页显示课程信息表里的数据,就不得不用到外键。

本文将阐述:
1、哪一个该做主键表?哪一个该做外键表?它们的区别是什么?
2、创建指向同一个模型的多个外键数据迁移时报错怎么办?
3、Django中指向同一模型的外键反向关联产生了冲突怎么办?
4、怎样给外键增加related_name属性,自定义关联名称?
5、外键删除常用属性介绍
6、数据迁移中的常见错误汇总
7、编程过程中遇到的一些问题和感悟

接下来,逐个解答:
1、哪一个该做主键表?哪一个该做外键表?它们的区别是什么?
课程信息表包含课程机构表里的数据,即课程信息表需要填写是哪个机构,故将机构表和信息表做内连接,机构表中的主键字段(机构名称)在信息表中做外键,而机构表没有外键,故机构表是主键表,信息表是外键表。
区别就是主键表的主键字段在外键表中做外键,而主键表自己却没有外键。
鸣谢今春看又过何日是归年的数据库中主键与外键的关系,通俗易懂

2、创建指向同一个模型的多个外键数据迁移时报错怎么办?
解决方法:添加不同的related_name,注意related_name的首个单词一定不可相同,否则会报错。
鸣谢Aaron_MK的Django的那些坑

3、Django中指向同一模型的外键反向关联产生了冲突怎么办?
直接将related_name赋值为加号或以加号结尾的字符串,即可实现禁用反向映射
上代码

course_org = models.ForeignKey(CourseOrg,related_name='org_name+', null=True, blank=True,max_length=50,on_delete=models.SET_NULL, verbose_name="课程机构")
cname = models.ForeignKey(CourseOrg,related_name='course_name+',null=True, blank=True, max_length=50,on_delete=models.SET_NULL,verbose_name="课程名")

鸣谢少女狙击手的python Django 反向访问器的外键冲突解决

4、怎样给外键增加related_name属性,自定义关联名称?
related_name=‘主键字段’
鸣谢mmaotai的related_name表面作用

5、外键删除常用属性介绍
CASCADE:这就是默认的选项,级联删除,你无需显性指定它。
PROTECT: 保护模式,如果采用该选项,删除的时候,会抛出ProtectedError错误。
SET_NULL: 置空模式,删除的时候,外键字段被设置为空,前提就是blank=True, null=True,定义该字段的时候,允许为空。
SET_DEFAULT: 置默认值,删除的时候,外键字段设置为默认值,所以定义外键的时候注意加上一个默认值。
SET(): 自定义一个值,该值当然只能是对应的实体了
鸣谢lucky__peng的django中on_delete

6、数据迁移中的常见错误汇总
6.1ERRORS:
auth.User.groups: (fields.E304) Reverse accessor for 'User.groups' clashes with reverse accessor for 'UserProfile.groups'.

HINT: Add or change a related_name argument to the definition for 'User.groups' or 'UserProfile.groups'.

auth.User.user_permissions: (fields.E304) Reverse accessor for 'User.user_permissions' clashes with reverse accessor for 'UserProfile.user_permissions'.

HINT: Add or change a related_name argument to the definition for 'User.user_permissions' or 'UserProfile.user_permissions'.

users.UserProfile.groups: (fields.E304) Reverse accessor for 'UserProfile.groups' clashes with reverse accessor for 'User.groups'.

HINT: Add or change a related_name argument to the definition for 'UserProfile.groups' or 'User.groups'.

users.UserProfile.user_permissions: (fields.E304) Reverse accessor for 'UserProfile.user_permissions' clashes with reverse accessor for 'User.user_permissions'.

HINT: Add or change a related_name argument to the definition for 'UserProfile.user_permissions' or 'User.user_permissions'

用户认证模型类数据迁移报错,报错原因:是继承了AbstractUser类,没有在setting文件里面声明使用自定义的类User。解决办法:在配置文件settings中声明使用自定义的User类:

# 指定使用自定义的模型类:
AUTH_USER_MODEL = 'users.User'
#users是应用名称,User是模型类的名称。

鸣谢571428的python 用户认证模型类数据迁移报错

6.2 The field admin.LogEntry.user was declared with a lazy reference to 'user.user',
but app 'user' doesn't provide model 'user'.
翻译过来就是用户应用程序‘用户’不提供模型‘用户’。
解决方案: 1. 先把迁移的文件删除掉。 2.然后把配置的数据库删掉重新创建。3.重新创建后迁移即可。
鸣谢菜鸟初成长的django执行迁移文件报错 用户应用程序‘用户‘不提供模型‘用户‘

6.3Migration admin.0001_initial is applied before its dependency users.
出现这种问题的原因是之前执行过run manage.py task中的:migrate,然后再次执行:migrate users #users为app名称,解决办法是,删掉数据库中的所有表,并删除app下的migrations文件夹,然后再执行:makemigrations users, migrate users
鸣谢geerniya的Django报错——Migration admin.0001_initial is applied before its dependency users.

6.4raise FieldDoesNotExist("%s has no field named '%s'" % (self.object_name, field_name))
django.core.exceptions.FieldDoesNotExist: CourseOrg has no field named 'name'
其实只因为是你还没更改adminx文件。解决如下:把class XXAdmin里没有的字段删除即可。特别注意,adminx.py里面的文件是展示后台可选选项的,修改完models.py文件,也要改adminx.py文件。
鸣谢django的raise FieldDoesNotExist('%s has no field named %r' % (self.object_name, field_name))

7、编程过程中遇到的一些问题和感悟
MySQLdb._exceptions.ProgrammingError: (1146, "Table 'mxonline.django_content_type' doesn't exist")

遇到这个特殊的问题,问度娘无果后,认真翻看教程,发现要清空所有migrations.py文件夹下除__init__.py的其他文件和MySQL数据库中的表后,再做迁移,经过一次次失败后终于知道在上步操作之后要把最底层人人都可调用的users表先做迁移,在常规迁移其他的表。最后得出结论:机构表是主键表,课程表是外键表,机构表需要提供外键给课程表,提供完了之后,机构表写一个函数,用于导入课程表,views里面写获取的逻辑(把CourseOrg作为一个对象传递出去),配置url,交给setting,在html文件中显示出来。

感悟就是要理清楚问题的来龙去脉,逐个击破,有些复杂的问题要学会分解,毕竟现在还不是强人工智能时代,搜索引擎并没有足够“智能”,遇到不熟悉的知识点,要学会主动补充背景知识。最后,要好好思考。

你可能感兴趣的:(Django大坑之外键设置外键冲突)