参考资料
https://zhuanlan.zhihu.com/p/427308152
一对多
首先来说说一对多,这个关联关系经常用到,多的一方通过models.ForeignKey进行关联。如下示例:
from django.db import models
class Department(models.Model):
name = models.CharField(max_length=20)
create_data = models.DateField(auto_now_add=True)
is_delete = models.BooleanField(default=False) # default=False,在数据库中表现为0
class Meta:
# 这里定义了db_table的话,那么迁移后表名就是department这个了,不会是应用名_类名小写(例如:framework_department)
db_table = "department"
class Employee(models.Model):
name = models.CharField(max_length=20)
age = models.IntegerField()
gender = models.IntegerField(default=0)
# decimal_place = 2表示两位小数,max_digits表示8个数字,包括小数的两位
salary = models.DecimalField(max_digits=8,decimal_places=2)
# null=True 表示可以为空,blank=True表示django后台管理输入这个字段可以为空
comment = models.CharField(max_length=300,null=True,blank=True)
hire_data = models.DateField(auto_now_add=True)
department = models.ForeignKey("Department", on_delete=models.CASCADE)
# department = models.ForeignKey("Department", related_name = 'employees', on_delete=models.CASCADE) # 加了related_name = 'employee'后,在进行查询一个部门的全部员工时就不用employee_set了,直接使用employee即可。其余方法和使用employee_set一致。
class Meta:
db_table = "employee"
以上定义了两个模型,员工和部门是一对多关系,员工属于多的一方,所以使用了models.ForeignKey来与部门进行关联。关联的模型如果是定义在一个py文件里的话,那么可以直接写模型名称即可,例如:Department就可以直接使用,但是如果要关联不在一个py文件里的模型,那么就要通过:应用名.模型名使用(例如:user.User)。
在命令行终端输入以下命令,在MySQ中生成数据表。
python3 manage.py makemigrations
python3 manage.py migrate
新增数据
新增Department
deparment = Department.objects.create(name="生产部1")
新增Employee
employee = Employee.objects.create(name="小明", age=18, gender=0, salary=8000.50, comment="新入职员工", department=deparment)
新增多个employee
Employee.objects.create(name="小明", age=18, gender=0, salary=8000.50, comment="新入职员工",
department=Department.objects.get(id=4))
Employee.objects.create(name="小张", age=18, gender=0, salary=9000.50, comment="新入职员工",
department=Department.objects.filter(id=4)[0])
更新一个员工所属的部门
Employee.objects.filter(id=1).update(department=5)
这里要注意的是,更新就不用传一个实例对象了,只需要传入部门id即可。传入实例对象会报错。
根据条件删除
删除指定部门下的所有员工
Employee.objects.filter(department=2).delete()
删除员工
Department.objects.filter(id=6).delete()
查询数据
employee = Employee.objects.get(id=4)
employee_belong_department = employee.department
employee_belong_department_name = employee_belong_department.name
print(employee_belong_department)
一个部门的全部员工
department = Department.objects.get(id=1)
all_employee= department.employee_set.all()
或者
all_employee = department.employee_set.values()
或者
all_employee = department.employee_set.values_list()
或者
department = Department.objects.get(id=7)
all_employee2 = department.employees.filter(id__in=[31,32]).all()
使用外键时,一般都会定义一个删除的关联操作。什么意思呢?如下:
department = models.ForeignKey("Department", on_delete=models.CASCADE)
如果一个模型使用了外键。那么在对方那个模型被删掉后,该进行什么样的操作。可以通过on_delete来指定。可以指定的类型如下:
CASCADE:级联操作。如果外键对应的那条数据被删除了,那么这条数据也会被删除。
PROTECT:受保护。即只要这条数据引用了外键的那条数据,那么就不能删除外键的那条数据。如果我们强行删除,Django就会报错。
SET_NULL:设置为空。如果外键的那条数据被删除了,那么在本条数据上就将这个字段设置为空。如果设置这个选项,前提是要指定这个字段可以为空。
SET_DEFAULT:设置默认值。如果外键的那条数据被删除了,那么本条数据上就将这个字段设置为默认值。如果设置这个选项, 前提是要指定这个字段一个默认值 。
SET():如果外键的那条数据被删除了。那么将会获取SET函数中的值来作为这个外键的值。SET函数可以接收一个可以调用的对象(比如函数或者方法),如果是可以调用的对象,那么会将这个对象调用后的结果作为值返回回去,可以不用指定默认值 。
DO_NOTHING:不采取任何行为。一切全看数据库级别的约束。