今天,小叮当来为大家继续分享Django干货~
主要内容有:常用的查询、常用字段类型及常用参数、表关系的实现
一、常用的查询
常用的查询方法总结
#1.获取所有记录
rs = User.objects.all()
#2.获取第一条数据
rs = User.objects.first()
#3.获取最后一条数据
rs = User.objecsts.last()
#4.根据参数提供的条件获取过滤后的记录
rs = User.objects.filter(name='xiaodingdang')
#filter(**kwargs)方法:根据参数提供的提取条件,获取一个过滤后的QuerySet。
#5.排除name等于xiaodingdang的记录
rs = User.objects.exclude(name='xiaodingdang')
#6.获取一个记录对象
rs = User.objects.get(name= 'xiaodingdang')
#get返回的对象具有唯一性质,如果符合条件的对象有多个,则get报错!
#7.对结果排序order_by
rs = User.objects.order_by('age')
#8.多项排序
rs = User.objects.order_by('age','id')
#9.逆向排序 (在条件的前面加个负号)
rs = User.objects.order_by('-age')
#10.将返回来的QuerySet中的Model转换为字典
rs = User.objects.all().values()
#11.获取当前查询到的数据总数
rs = User.objects.count()
由于其使用方法在零基础入手Django(六):模型基础1中已经为大家介绍过,这里只挑选出来几个具有代表性的进行演示。
(1)使用order_by逆向排序
重新定义查询视图函数
#查询数据
def search_user(request):
rs = User.objects.all()
print('我是默认查询结果',rs)
order_rs = User.objects.order_by('-age')
print('我是倒序查找',order_rs)
return HttpResponse('我在使用order_by方法查询')
在浏览器中访问
在Pycharm后台端,查看输出结果
可以看到,默认查询是按id正序排列。使用order_by方法后,我们成功使得输出按照age进行了逆向排列。
值得注意,在按age倒序输出时,相同age的数据还是按id从小到大排列了,例如age=18时,先输出了id=1的xdd才输出了id=2的小叮当。
这时我们就可以使用order_by,对多个字段进行排序,使得当age相同时,便按id从大到小进行排序。
在视图函数中添加如下语句:
ors = User.objects.order_by('-age','-id')
print('我使用了多字段',ors)
在浏览器中访问后,在后台查看
(2)values将输出结果字典化
重新定义查询视图函数
#查询数据
def search_user(request):
rs = User.objects.all()
print('我是默认查询结果',rs)
vrs = User.objects.all().values()
print('我是字典化后的结果',vrs)
return HttpResponse('我在使用values字典化查询结果')
在浏览器中查看
在pycharm后台端查看输出结果
(3)count查询数据总数
在查询视图函数中,添加如下代码
num = User.objects.count()
print('数据总数为',num)
在浏览器中查看
在pycharm后台端查看结果
2.常用的查询条件总结
#1.等于号 exact
rs = User.objects.filter(name__exact='xiaodingdang')
#iexact是忽略了大小写匹配的等于
#2.包含 contains
rs = User.objects.filter(name__contains='xiao')
#icontains是忽略了大小写匹配的包含
#3.以什么开始 startswith
rs = User.objecsts.filter(name__startswith='xiao')
#istartswith是忽略了大小写的startswith
#4.以什么结尾 endswith
rs = User.objects.filter(name__endswith='dang')
#iendswith是忽略了大小写的endswith
#5.成员所属 in
rs = User.objects.filter(age__in=[18,19,20])
#6.大于 gt
rs = User.objects.filter(age__gt=18)
#7.大于等于 gte
rs = User.objects.filter(age__gte=18)
#8.小于 lt
rs = User.objects.filter(age__lt=20)
#9.小于等于 lte
rs = User.objects.filter(age__lte=20)
#10.区间 range
rs = User.objects.filter(age__range=(18,20))
#11.判断是否为空
rs = User.objects.filter(city__isnull=True)
定义查询视图函数
#查询数据
def search_user(request):
ers = User.objects.filter(name__exact='小叮当')
print('查询name等于小叮当的数据',ers)
crs = User.objects.filter(name__contains='x')
print('查询name包含了x的数据',crs)
srs = User.objects.filter(name__startswith='神仙')
print('查询name以神仙开头的数据',srs)
endrs = User.objects.filter(name__endswith='叮当')
print('查询name以叮当结尾的数据',endrs)
grs = User.objects.filter(age__gt=19)
print('查询age大于19的数据',grs)
lrs = User.objects.filter(age__lt=19)
print('查询age小于19的数据',lrs)
rrs = User.objects.filter(age__range=(18,19))
print('查询age在[18,19)的数据',rrs)
irs = User.objects.filter(age__in=[18,19])
print('查询age为18和19的数据',irs)
nrs =User.objects.filter(city__isnull=True)
print('判断city字段是否为空',nrs)
return HttpResponse('我在使用条件查询数据')
在浏览器中访问
在后台查看结果
其中值得注意的是,在django中使用条件查询时,相当于使用了sql语句中的where。其语法是:字段名__规则 (字段名和规则之间是两条下划线)
例如:
nrs =User.objects.filter(city__isnull=True)
就相当于sql语句
select * from .... where city is null
二、常用字段类型及常用参数
常用的字段类型映射关系
在models.py中我们可以看到,我们只使用了AutoField(自增长类型)、CharField(字符类型)、IntegerField(整数类型)等数据类型。
其实,在Django中还有其它几种常用的字段类型,它们的映射关系如下
常用的字段类型总结如下:
1.IntegerField:整型,映射到数据库中的int类型。
2.CharField:字符类型,映射到数据库中的varchar类型,通过max_length指定最大长度。
3.TextField:文本类型,映射到数据库中的text类型。
4.BooleanField:布尔类型,
映射到数据库中的tinyint类型,在使用的时候
传递True/False进去。如果要可以为空,则用NullBooleanField。
5.DateField:日期类型,没有时间。
映射到数据库中是date类型。在使用的时候,
可以设置DateField.auto_now每次保存对象时,自动设置该字段为当前时间。
设置DateField.auto_now_add当对象第一次被创建时自动设置当前时间。
6.DateTimeField:日期时间类型,
映射到数据库中的是datetime类型。
在使用的时候,传递datetime.datetime()进去。
Field的常用参数总结如下:
1.primary_key:指定是否为主键。
2.unique:指定是否唯一。
3.null:指定是否为空,默认为False。
4.blank:等于True时form表单验证时可以为空,默认为False。
5.default:设置默认值。
6.DateField.auto_now:每次修改都会将当前时间更新进去,只有调用
QuerySet.update方法将不会更新,这个参数只是Date和DateTime以及
TimModel.save()方法才会调用e类才有的。
DateField.auto_now_add:第一次添加进去,都会将当前时间设置进去,
以后修改,不会修改这个值。
2.使用常用类型创建数据表
(1)我们在models.py中新建Field_Test模型类作为一张新的表
class Field_Test(models.Model): name = models.CharField(max_length=30,unique=True)
age = models.IntegerField()
note = models.TextField()
gender = models.BooleanField(default=True)
create_time = models.DateField(auto_now_add=True)#第一次存入数据的时间 update_time = models.DateTimeField(auto_now=True)#每次更新就会修改
(2)在pycharm的tools中找到"Run manage.py Task..."
执行makemigrations model_test
(3)执行migrate model_test
(4)使用xshell进行查看
执行命令“mysql -u xdd(用户名) -p(输入密码)”
执行命令“use mydb;"
执行命令”show tables;“
执行命令”desc model_test_field_test;"
3.向表中插入数据
(1)重新定义添加数据的视图函数
from .models import Field_Test
def add_user(request):
Field_Test.objects.create(name='小叮当',age=17,
note='我是小叮当',gender=False)
return HttpResponse('小叮当在向field_test中添加数据!')
(2)在浏览器中访问
(3)通过xshell进行查看
4.更新数据
(1)重新定义添加数据的视图函数
def add_user(request):
rs = Field_Test.objects.get(id=1)
rs.name = "快乐小叮当"
rs.save()
return HttpResponse('小叮当在更新数据!')
(2)在浏览器中访问
(3)通过xshell查看
可以看到,数据更新的时间已经自动更新。但是显示的更新的时间与我们真实的时间相差了8个小时~大家知道这是时区默认设置导致的即可。
值得注意,只有使用.save()方法更新数据,系统才会自动更新时间。而使用update方法更新,则不会调用auto_now自动更新时间。
三、表关系的实现
1.表关系示意图
2.示例
为了明确在django中如何创建丰富的表关系,小叮当为大家示例如下
(1)表关系图
假如有下面这几张表
它们的关系可以这样表示:
(2)在项目中新建app,并注册
在项目中新建名为db_test的app用来实现表关系。在Tools中打开Run manage.py Task...
执行命令“startapp db_test"
在项目处,右键将创建好的app下载下来
在项目的settings文件中注册创建好的app
(3)创建表
我们在建好的”db_test“的models.py中创建表。值得注意,当出现一对多,多对多,一对一等复杂关系时,我们一般先从”一“这一端来创建表。
在models.py中创建模型类如下:
#1.创建学院信息表
class Department(models.Model):
d_id = models.AutoField(primary_key=True)
d_name = models.CharField(max_length=30)
#2.创建学生信息表
class Student(models.Model):
s_id = models.AutoField(primary_key=True)
s_name = models.CharField(max_length=30)
#实现一对多关系ForeignKey 其中on_delete为必填字段使用级联删除CASCADE
department = models.ForeignKey('Department',on_delete=models.CASCADE)
#3.课程信息表
class Course(models.Model):
c_id = models.AutoField(primary_key=True)
c_name = models.CharField(max_length=30)
#实现多对多关系 ManyToManyField
student = models.ManyToManyField('Student')
#4.学生详细信息表
class Stu_detail(models.Model):
# 实现一对一关系OneToOneField 其中on_delete为必填字段使用级联删除CASCADE
student = models.OneToOneField('Student',on_delete=models.CASCADE)
age = models.IntegerField()
gender = models.BooleanField(default=1)
city = models.CharField(max_length=30,null=True)
在Pycharm的Tools中打开Run manage.py Task...
执行 makemigrations
执行 migrate
在xshell 的mysql中 执行 show tables;
执行 desc db_test_department; 查看学院信息表
执行 desc db_test_student; 查看学生信息表
可以看到,学生信息表中自动为我们关联生成了”department_id"外键,也就是department表的d_id
关于级联删除:
只有引用的数据全部删除后,才可以删除被引用表中的父类数据。例如,学院信息表中1代表计算机学院。在学生信息表中,小明、小红、小花都是计算机学院,他们的外键值都是1,想要在学院信息表中删除计算机学院,需要在学生信息表中先删除了引用计算机学院的小明、 小红、小花。
执行 desc db_test_course; 查看课程表
执行 desc db_test_stu_detail; 查看学生详细信息表
可以看到,已经按照我们的设置,学生详细信息表和学生表建立了一对一的关系。
再次执行,show tables;
我们看到,我们已实现了学生表与课程表的多对多关系,系统已为我们自动生成了中间信息表“db_test_course_student"。
执行 desc db_test_course_student; 进行查看,结果如下
网友评论