django模型 数据库设计学习
django模型 数据库设计学习:
作用:设计的好,会清晰,且易于理解,后续开发也事半功倍,易于维护。
本文转载自:https://blog.csdn.net/weixin_46451496/article/details/106261805
基本原则:
1.一对一的表,两表的属性实际上完全可以合并成一个表,共用一个主键即可;
2.一对多的表,可以设中间关联表,也可以将关联表并入“多”这头;若设独立关联表,则可引入“多”这头的主键作为其主键,也可另立主键并将“一”和“多”两表的主键作为关联表的外键;
3.多对多的表,则必须设中间关联表,关联表设独立主键,并引入两个“多”头的表的主键作为关联表的外键。
4.能用1对1的,就不用1对多;能用1对多的,就不用多对多,往简单化方向靠;
5.能当属性处理的,尽量当属性,而不是当实体处理去另立新表,这样可使问题简化。
6.把意义相近联系紧密的属性放在一张表内,而不是拆在多张表中。
三种关系解读:
ForeignKey: 多对一
ManyToManyField:多对多
OneToOneField: 一对一
- 一对多模型
一对多的关系,例如员工跟部门。一个部门有多个员工。那么在django怎么建立这种表关系呢?
其实就是利用外键,在多的一方,字段指定外键即可。例如员工和部门,员工是多,所以在员工表直接部门即可。
示例(见19行):
123456789101112131415161718192021221
class
Department(models.Model):
2
name
=
models.CharField(max_length
=
20
)
3
create_data
=
models.DateField(auto_now_add
=
True
)
4
is_delete
=
models.BooleanField(default
=
False
)
5
6
class
Meta:
7
db_table
=
"department"
8
9
10
class
Employee(models.Model):
11
name
=
models.CharField(max_length
=
20
)
12
age
=
models.IntegerField()
13
gender
=
models.IntegerField(default
=
0
)
14
# decimal_place = 2表示两位小数,max_digits表示8个数字,包括小数的两位
15
salary
=
models.DecimalField(max_digits
=
8
,decimal_places
=
2
)
16
# null=True 表示可以为空,blank=True表示django后台管理输入这个字段可以为空
17
comment
=
models.CharField(max_length
=
300
,null
=
True
,blank
=
True
)
18
hire_data
=
models.DateField(auto_now_add
=
True
)
19
department
=
models.ForeignKey(
"Department"
)
20
21
class
Meta:
22
db_table
=
"employee"
拓展:
1)在设置外键时,需要通过on_delete选项指明主表删除数据时,对于外键引用表数据如何处理,在django.db.models中包含了可选常量:
关联属性on_delete选项的取值models.CASCADE 此为默认值,级联删除,会删除关联数据
-department = models.ForeignKey(‘Department’, on_delete=models.CASCADE)models.PROTECT 只要存在关联数据就不能删除
department = models.ForeignKey(‘Department’, on_delete=models.PROTECT)
models.SET_NULL 删除数据后关联字段设置为NULL,仅在该字段允许为null时可用(null=True) -
2).如果关联的字段不在该应用文件夹的model.py中,那么要写成这样
department = models.ForeignKey("(应用文件夹名).Department")
还有一个需要特别注意:12department
=
models.ForeignKey(
"Department"
,related_name
=
'employee'
)时,
通过部门查找员工的是用employee。如果不设置的话,是用默认的employee_set(类名的小写
+
_set)
一对多的查询:
1234567891011一个员工所属的部门(查出来的是对象):
a
=
Employee.objects.get(
id
=
1
)
b
=
a.department
一个部门的全部员工(查出来的是对象):
a
=
Department.objects.get(
id
=
1
)
b
=
a.employee_set.
all
()
- 多对多模型
多对多的关系,例如学生与社团。一个学生可以进多个社团,一个社团可以有多个学生。那么在django怎么建立这种表关系呢?
django建立多对多关系有两种方法。
方法一:
1234561
class
Student(models.Model):
2
name
=
models.CharField(max_length
=
16
)
3
birthday
=
models.DateField()
4
class
Club(models.Model):
5
name
=
models.CharField(max_length
=
16
)
6
members
=
models.ManyToManyField(
"Student"
)
只需要在任意一方加上类似第6行的ManyToManyField就可以了。Django会自动为多对多关联关系创建一张表,用于两张表的联系。
那么查询呢?
1234561.
一个社团的全部成员(查出来的是对象)
c
=
Club.objects.get(
id
=
1
)
c.members.
all
()
2.
一个成员的全部社团(查出来的是对象)
s
=
Student.objects.
filter
(
id
=
1
)
s.club_set.
all
()
# 类名的小写+_set
方法二:(比较灵活)
自己手动建立一张表关联联系。
12345678910class
Student(models.Model):
name
=
models.CharField(max_length
=
16
)
birthday
=
models.DateField()
class
Club(models.Model):
name
=
models.CharField(max_length
=
16
)
class
Membership(models.Model):
student
=
models.ForeignKey(
"Student"
)
club
=
models.ForeignKey(
"Club"
)
那么这种方式建表怎么查询呢?
12345678910111213141516171819一个学生加入的全部社团:
a
=
Student.objects.get(
id
=
1
)
b
=
a.membership_set.
all
()
# 查出来的是对象
for
i
in
b:
print
(i.club.name)
一个社团的全部学生:
a
=
Club.objects.get(
id
=
1
)
b
=
a.membership_set.
all
()
# 查出来的是对象
for
i
in
b:
print
(i.student.name)
- 自关联模型
自关联模型,就是表中的某一列,关联了这个表中的另外一列。最典型的自关联模型就是地区表。省、市、县都在一张表里面。省的pid为null,市的pid为省的id,县的pid为市的id。
示例:
1234567class
Area(models.Model):
name
=
models.CharField(max_length
=
20
, verbose_name
=
'名称'
)
# 自关联(特殊的一对多): 生成的字段名 parent_id
parent
=
models.ForeignKey(
'self'
, verbose_name
=
'上级行政区划'
)
class
Meta:
db_table
=
'tb_areas'
verbose_name
=
'行政区划'
那么,怎么查询呢?
如果知道一个市,叫a市,想查他属于什么省。
12345a
=
Area.objects.get(
id
=
1
)
# b就是a市的省份的对象
b
=
a.parent
如果知道一个省,叫a省,想查他有什么市。
12345a
=
Area.
object
.get(
id
=
1
)
# b就是a省的全部市的对象
b
=
a.area_set.
all
()
#类名小写+'_set'b
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix