一对一 (models.OneToOneField)
id_card = models.OneToOneField('demo4.IdCard', null=True, blank=True, on_delete=models.CASCADE)
一对多 (外键)models.ForeignKey
dept = models.ForeignKey('DeptModel', verbose_name='员工所属的部门', related_name='emps_list', null=True, blank=True, on_delete=models.SET_NULL)
多对多 models.ManyToManyField related_name='role_emps_list',
roles = models.ManyToManyField('demo4.RoleModel', related_name='role_emps_list', db_table='t_emp_roles', null=True, blank=True)
null=True 可以为None, blank=True 可以为空字符串 ''
一对一 身份证模型
from django.db import models
from demo1.base_model import BaseModel
# Create your models here.
class IdCard(BaseModel):
"""省份证的模型类"""
id_number = models.CharField(verbose_name='省份证号码', unique=True, max_length=18)
start_date = models.DateField(verbose_name='发证日期', null=True, blank=True)
end_date = models.DateField(verbose_name='发证日期', null=True, blank=True)
class Meta:
db_table = 't_id_card'
verbose_name = '员工表'
verbose_name_plural = verbose_name
ordering = ['id']
class RoleModel(BaseModel):
"""权限的模型类, 一个员工可以拥有多个权限, 一个权限可以被多个员工所拥有"""
name = models.CharField(verbose_name='权限的名称', unique=True, max_length=18)
class Meta:
db_table = 't_role'
verbose_name = '权限表'
verbose_name_plural = verbose_name
ordering = ['id']
员工与权限的多对多关联模型 员工与部门间一对多关联模型
from datetime import date
from django.db import models
from django.db.models import Model
from demo1.base_model import BaseModel
# Create your models here.
class JobChoices(models.TextChoices):
"""枚举类"""
MR = 'MR', '部门经理'
CE = 'CE', '普通雇员'
PR = 'PR', '总裁级别'
# 员工的模型类
class Employee(BaseModel):
name = models.CharField(verbose_name='员工姓名', max_length=20, unique=True)
job = models.CharField(verbose_name='员工职位', max_length=2, choices=JobChoices.choices, default=JobChoices.CE)
entry_date = models.DateField(verbose_name='入职日期', default=date.today())
sal = models.IntegerField(verbose_name='级别薪资')
bonus = models.SmallIntegerField(verbose_name='津贴', default=0)
is_leave = models.BooleanField(verbose_name='是否离职', default=False)
dept = models.ForeignKey('DeptModel', verbose_name='员工所属的部门', related_name='emps_list', null=True, blank=True, on_delete=models.SET_NULL)
id_card = models.OneToOneField('demo4.IdCard', null=True, blank=True, on_delete=models.CASCADE)
# 表示:员工拥有的多个角色,员工和角色之前是多对多的关系。在数据库通过第三张表来描述的。
# 可以自己定义第三张表的名字:db_table='t_emp_roles'
roles = models.ManyToManyField('demo4.RoleModel', related_name='role_emps_list', db_table='t_emp_roles', null=True, blank=True)
class Meta:
db_table = 't_emp'
verbose_name = '员工表'
verbose_name_plural = verbose_name
ordering = ['id']
def __str__(self):
# get_ + 属性名字 + _display
return f"当前的员工是:{self.name}, 职位:{self.get_job_display()}"
# 部门, 之前存在有层级关系(一对多)
# 一个类,内部之前的一对多关系,也叫树形结构模型类,
class DeptModel(BaseModel):
name = models.CharField(verbose_name='部门名字', max_length=20, unique=True)
address = models.CharField(verbose_name='部门地址', max_length=100, null=True, blank=True)
parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL)
class Meta:
db_table = 't_dept'
verbose_name = '部门表'
verbose_name_plural = verbose_name
ordering = ['id']
def __str__(self):
# get_ + 属性名字 + _display
return f"当前的部门是:{self.name}"
跨app的权限模型(demo4app)
from django.db import models
from demo1.base_model import BaseModel
# Create your models here.
class IdCard(BaseModel):
"""省份证的模型类"""
id_number = models.CharField(verbose_name='省份证号码', unique=True, max_length=18)
start_date = models.DateField(verbose_name='发证日期', null=True, blank=True)
end_date = models.DateField(verbose_name='发证日期', null=True, blank=True)
class Meta:
db_table = 't_id_card'
verbose_name = '员工表'
verbose_name_plural = verbose_name
ordering = ['id']
class RoleModel(BaseModel):
"""权限的模型类, 一个员工可以拥有多个权限, 一个权限可以被多个员工所拥有"""
name = models.CharField(verbose_name='权限的名称', unique=True, max_length=18)
class Meta:
db_table = 't_role'
verbose_name = '权限表'
verbose_name_plural = verbose_name
ordering = ['id']
view中的联表查询
from datetime import date
from django.db.models import Count
from django.http import HttpResponse
from django.shortcuts import render
# Create your views here.
from demo3.models import JobChoices, Employee, DeptModel
from demo4.models import IdCard, RoleModel
def test_db4(request):
# 给员工增加部门
# emp = Employee.objects.create(name='lisi', job=JobChoices.CE, entry_date=date(2020, 10, 9), sal=3500, bonus=800)
#
# emp.dept_id = 6
# emp.save() # 触发数据库的修改
# emps = Employee.objects.all()
# d = DeptModel.objects.get(pk=4)
#
# for emp in emps:
#反向查询按类名小写_set或者related_name
# d.employee_set.add(emp)
# 一对一新增数据
# ic = IdCard.objects.create(id_number='11111111111')
# emp = Employee.objects.get(pk=8)
# emp.id_card = ic
# emp.save()
# 多对一的新增数据
# r1 = RoleModel.objects.create(name='销售人员')
# r2 = RoleModel.objects.create(name='出库人员')
# r3 = RoleModel.objects.create(name='财务人员')
# emp = Employee.objects.get(pk=3)
# r1.role_emps_list.add(emp) # 给ID为3的员工授予了一个角色:销售人员
# r2.role_emps_list.add(emp) # 给ID为3的员工授予了一个角色:出库人员
# r3.role_emps_list.add(emp) # 给ID为1的员工授予了一个角色:财务人员
# emp.roles.add(r1, r2, r3)
# emp.save()
# 关联查询
# 1、查询2020年入职的员工姓名以及该员工的所在部门名称
# result = Employee.objects.filter(entry_date__year=2020).values('name', 'dept__name')
# 2、 查询省份号码是:11111111111。 的员工的姓名,以及该员工所属的部门
# dept 是员工的关联对象, 如果要访问:dept里面的属性,采用"__", 不过,主机ID可以不用__
# result = Employee.objects.filter(id_card__id_number='11111111111').values('name', 'dept__name', 'dept_id')
# 3、 查询,每个部门名字、地址以及该部门下面的员工个数
result = DeptModel.objects.values('name', 'address').annotate(c=Count('emps_list__name'))
# 4、查询拥有角色数量超过1的 员工姓名以及他所拥有的角色数量。
result = Employee.objects.annotate(c=Count('roles__name')).filter(c__gt=1).values('name', 'c')
# 5、 查询每个部门的名字以及它里面的员工数量,并且按照员工数量的个数降序排序。
result = DeptModel.objects.annotate(c=Count('emps_list__name')).order_by('-c').values('name', 'c')
for d in result:
print(d)
return HttpResponse('test_db4')