前言

mysql断断续续地学,一直对诸如外键的概念不甚清晰,今天做一个备忘。在这篇博文的基础上,加上了一些自己的理解。

建表

#_*_coding:utf-8_*_
from django.db import models
 
# Create your models here.
 
class Colors(models.Model):
    colors=models.CharField(max_length=10) #蓝色
    def __str__(self):
        return self.colors
 
class Ball(models.Model):
    color=models.OneToOneField("Colors")  #与颜色表为一对一,颜色表为母表
    description=models.CharField(max_length=10) #描述
    def __str__(self):
        return self.description
 
class Clothes(models.Model):
    color=models.ForeignKey("Colors")   #与颜色表为外键,颜色表为母表
    description=models.CharField(max_length=10) #描述
    def __str__(self):
        return self.description   
     
class Child(models.Model):
    name=models.CharField(max_length=10)   #姓名  
    favor=models.ManyToManyField('Colors')    #与颜色表为多对多
    

一对一(models.OneToOneField)

子表从母表中选出一条数据一一对应,母表中选出来一条就少一条,子表不可以再选择母表中已被选择的那条数据。一般用于某张表的补充,比如用户基本信息是一张表,但并非每一个用户都需要有登录的权限,不需要记录用户名和密码,此时,合理的做法就是新建一张记录登录信息的表,与用户信息进行一对一的关联,可以方便的从子表查询母表信息或反向查询。

## 增加

color_obj=models.Colors.objects.create(colors="黑")  #先在母表中创建颜色,并实例化给颜色表对象
models.Ball.objects.create(color=color_obj,description="黑球")  #更新Ball表,color字段为颜色表对象,添加description字段

## 删除
models.Ball.objects.get(description="灰球").delete()

## 修改
color_obj=models.Colors.objects.get(colors="黑") #.get()等同于.filter().first()
color_obj.colors="灰"
color_obj.save()
models.Ball.objects.filter(description="黑球").update(color=color_obj,description="灰球") 

## 查询
### 子表查询母表
models.Ball.objects.get(description="红球").color.colors

### 母表查询子表
models.Colors.objects.get(colors="红").ball.description

一对多(models.ForeignKey)

子表从母表中选出一条数据一一对应,但母表的这条数据还可以被其他子表数据选择。这里的一和多指的是自身的表的数据在对方表里出现的次数,一次为一,多次为多。比如每个员工归属于一个部门,那么就可以让员工表的部门字段与部门表进行一对多关联,可以查询到一个员工归属于哪个部门,也可反向查出某一部门有哪些员工。

## 查

color_obj=models.Colors.objects.get(colors="红")
color_obj.clothes_set.all()
或
models.Clothes.objects.filter(color__colors="红")

多对多(models.ManyToManyField)

比如有多个孩子,和多种颜色。每个孩子可以喜欢多种颜色,一种颜色可以被多个孩子喜欢,对于双向均是可以有多个选择。

## 查

#写法1:
child_obj=models.Child.objects.get(name="小明")  #写法:子表对象.子表多对多字段.过滤条件(all()/filter())
print(child_obj.favor.all())
#写法2,反向从母表入手:
print(models.Colors.objects.filter(child__name="小明")) #母表对象.filter(子表表名小写__子表字段名="过滤条件")