开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第36天,点击查看活动详情
模型基础二
一,常用的字段类型映射关系![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8KF3za5N-1592067915665)(assets/1.png)]](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4568e261483d40389ac2372f4a470b4f~tplv-k3u1fbpfcp-zoom-in-crop-mark:1512:0:0:0.awebp)
二,字段常用参数
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
| 方法 | 功能 |
|---|---|
| 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是取别名
四,表关系
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 迁移序号