Django(7) - 常用的查询以及表关系的实现

108 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第36天,点击查看活动详情

模型基础二


一,常用的字段类型映射关系[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8KF3za5N-1592067915665)(assets/1.png)]

二,字段常用参数

primary_key=True	# 指定是否为主键
unique=True/False	# 指定是否唯一
null=True/False		# 是否允许为空,默认False
blank=True/False	# 等于True时form表单验证可以为空,默认False
default=默认值		 # 设置默认值
DateField.auto_now:	# 每次修改都会将当前时间更新进去,只有调用QuerySet.update方法将不再调用,这个参数只是Date和DateTime以及TimeModel.save()方法才会调用e类才有的
DateFiled.auto_now_add:	# 第一次添加进去,都会将当前时间设置进去,以后修改,不会修改这个值

自定义主键

id = models.AutoField(primary_key=True)

三,查询方式

1),查询方法

​ 每个Django模型类,都有用一个默认的管理器object[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HUbtGFtq-1592067915671)(assets/2.png)]

方法功能
Imforation.objects.all()返回所有的数据
Imforation.objects.defer('qq', 'cre_time')返回除了qq,cre_time这两个字段之外的所有数据
Imforation.objects.get(pk=1)返回只有一条数据(若结果又多个报错)
Imforation.objects.filter(sex=0)返回sex=0的所有数据
Imforation.objects.exclude(sex=0)返回除sex=0的所有数据
Imforation.objects.first()返回表格第一行数据对象
Imforation.objects.last()返回表格最后一行数据对象
Imforation.objects.values('name', 'age')返回指定字段的数据,没有指定的字段数据拿不到
Imforation.objects.only('name', 'age')返回指定字段的数据,没有指定的字段数据也能拿到
排序
mforation.objects.order_by('age')返回age字段排序的数据(小 -> 大)
Imforation.objects.order_by('-age')返回age字段排序的数据(大 -> 小)
切片
Imforation.objects.all()[:2]取前两个数据
or多条件查询
from django.db.models import Q用到or必须导入Q
Imforation.objects.filter( Q(age=21) | Q(age=19) )返回年龄是21或者19的数据
​ 2),条件查询
准确查询
Imforation.objects.filter(name__exact='A')准确匹配,name的值必须完全是A
Imforation.objects.filter(name__iexact='A')忽略大小写匹配
模糊查询
Imforation.objects.filter(name__contains='l')模糊查询,只要name里面带l都返回
Imforation.objects.filter(age__icontains='l')忽略大小写模糊查询
指定值查询
Imforation.objects.filter(sex__in=[0, 1])指定在性别值是0,1的返回
Imforation.objects.filter(sex__in='01')指定在性别值是0,1的返回
大于小于
Imforation.objects.filter(id__gt=2)gt(大于)
Imforation.objects.filter(id__gte=2)gte(大于等于)
Imforation.objects.filter(id__gt=2)lt(小于)
Imforation.objects.filter(id__gt=2)lte(小于等于)
指定范围区间查询
Imforation.objects.filter(age__range=(15, 20))返回年龄值在15到20之间
3),聚合分组(aggregate,annotate )
1.统计数量
Imforation.objects.filter(age__gt=18).count()	# 计算年龄大于18的人数
2.平均值,最大值,最小值,求和
from django.db.models import Avg, Max, Min, Sum 
Imforation.objects.aggregate(Avg('age'))	# 年龄平均值
Imforation.objects.aggregate(Max('age')) 	# 年龄最大值
Imforation.objects.aggregate(Min('age')) 	# 年龄最小值
from django.db.models import Avg, Max, Min, Sum, Count 
Imforation.objects.values('age').annotate(Count('age')) 
<QuerySet [{'age': 18, 'age__count': 1}, {'age': 19, 'age__count': 2}, {'age': 20, 'age__count': 1}, {'age': 21, 'age__count': 2}, {'age': 129, 'age__count': 1}]>
# num是取别名

四,表关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MwctL3d5-1592067915675)(assets/3.png)]

class Imforation(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=20)  # 创建varchar的类
    age = models.SmallIntegerField(null=True)        # 创建tinyint字段的类
    sex = models.SmallIntegerField(default=1, null=True)   # 设置默认值
    qq = models.CharField(max_length=20, null=True)
    phone = models.CharField(max_length=20, null=True)
    cre_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    # verbose_name可以设置成一个人类认识的字段名,auto_now_add自动填充当前时间
    # detail = models.OneToOneField('Detail', on_delete=models.SET_NULL, null=True)
    grade = models.ForeignKey('Grade', on_delete=models.SET_NULL, null=True)
    # n_delete = models.SET_NULL代表参考表删除,相应的字段值为null,所以一定要设置null=True
    def __str__(self):
        return self.name, self.age

1)一对一(OneToOne)

class Detail(models.Model):
    college = models.CharField(max_length=20, default='')   # 学校
    Imforation = models.OneToOneField('Imforation', on_delete=models.CASCADE)
# on_delete=models.CASCADE,集联删除,是为了保持数据的一致性,参考表删除,这张表对应的数据删除

2),一对多(OneToMany)

class Grade(models.Model):
    name = models.CharField('班级名称', max_length=20)
    num = models.CharField('班期', max_length=20)

3),多对多(ManyToMany)

class Course(models.Model):
    name = models.CharField('课程名称', max_length=20)
    imforation = models.ManyToManyField('Imforation', through='Enroll')
# 这里Django会给你自动生成一张中间表,但是有时候会需要在第三张添加字段
自定义第三张表
1.回滚:python manage.py migrate app_name 0002(回滚回去的迁移文件的序号)
2.删除最后一次迁移文件
class Enroll(models.Model):
    imforation = models.ForeignKey('Imforation', on_delete=models.CASCADE)
    course = models.ForeignKey('Course', on_delete=models.CASCADE)
    c_time = models.DateTimeField('报名时间', auto_now_add=True)
    pay = models.FloatField('缴费金额', default=0)

总结

1. 创建迁移:python manage.py makemigrations
2. 查看迁移sql语句:python manage.py sqlmigrate 迁移序号
3. 应用迁移:python manage.py migrate
4. 回滚回指定迁移:python manage.py migrate app_name 迁移序号