ORM简介
Django框架中的ORM(Objects Realitional Mapping)即对象关系映射,是一种基于关系型数据库的程序技术,实际操作就是 通过类和对象对数据库进行操作,而不是通过SQL语句来操作数据库。
ORM把类映射成数据库中的表,把类的一个实例对象映射成数据库中的数据行,把类属性映射成表中的字段,通过对象的操作对应到数据库表的操作
适配多种常用的关系型数据库,如PostgreSQL,MySQL,Oracle,Sqlite3等
字段 | 说明 | 字段属性 |
---|---|---|
AutoField | 默认自增主键,(Primary_Key=True),Django默认建立id字段为主键 | |
CharField | 字符类型 | Max_length=32,需要明确字符长度 |
IntgerField | 整型int | |
DateField | 年月日时间类型 | auto_now=True,数据被更新后就会更新该字段;auto_now_add=True,数据第一次参数时产生,后续不再更新? |
DateTimeField | 年月日时分钟秒时间类型 | auto_now=True,数据被更新后就会更新该字段;auto_now_add=True,数据第一次参数时产生,后续不再更新? |
DecimalField | 混合精度的小数类型 | max_digits=3,限定数字的最大位数(含小数位);decimal_places=2,最多保留2位小数 |
BooleanField | 布尔字段,对应数据库tinyint类型数据长度只有1位 | 值为True或False |
TextField | 用于大文本 |
单表操作
1、创建表
在应用下models.py中创建User表
#必须引入models,from django.db import models
#必须继承models模块的Model子类,class user(models.Model),
执行迁移命令 才会生效
python manage.py makemigrations #生成一个数据库迁移记录的文件
python manage.py migrate#将更改真正提交到数据库执行
2、插入数据
方法一:
每个继承自models.Model的模型类,都会有一个objects对象被同时继承下来,这个对象就叫做管理器对象,数据库的增删改查可以用objects管理器对象来实现
User.objects.create(name=‘hc’,password=‘123’)
def register(request):
if request.method== 'GET':
return render(request,'register.html')
elif request.method=='POST':
username=request.POST.get('username') #根据html标签的name获取值
password=request.POST.get('password')
User.objects.create(name=username,password=password)#插入一条数据
return HttpResponse('注册成功')
方法二:
创建User的实例对象,然后调用save()方法保存
obj=User(name=‘hc’,password=‘123’)
obj.save()
在代码中,如下,因为username和password都是变量,从当前用户输入获取的
obj=User(name=username,password=password)
obj.save()
启动命令行模式操作Django模型,遇到的问题
直接在terminal 引入模型报错
原因是我的django项目没有启动,必须要先启动django项目,然后进入到cmd命令行模式下,启动shell模式,在该模式下可以操作django模型
3、查询数据
基础查询
1、all()查询所有数据,返回querySet 对象
User.objects.all() # 返回所有数据对象,不返回具体的数据
users=models.User.objects.all()
print(users)
【延伸】QuerySet对象
QuerySet对象是一个查询集,在你创建一个QuerySet对象的时候,Django并不会立即向数据库发出查询命令,只有在你需要用到这个QuerySet的时候才回去数据库查询。QuerySet 可以被构造,过滤,切片,做为参数传递,这些行为都不会对数据库进行操作。只要你查询的时候才真正的操作数据库
#queryset对象索引从1开始
objects是单个对象,queryset是许多对象。
迭代:
切片:对一个未查询的QuerySet对象切片,返回一个新的未查询的QuerySet对象此时仍然没有查询数据库
索引从0开始,切片时同样左闭右开原则
延伸内容参考博文:https://blog.csdn.net/aaronthon/article/details/81714506
2、values()查询所有数据的值
语法格式: Users.Objects.all().values #
返回querySet对象,结果类似于列表嵌套字典[{},{}],一个数据对象就是一个字典对象,每个字典对象中的key就是models中定义的属性
users=models.User.objects.all()
print(users)
print(users.values()) #查询所有数据的值
print(users[1:4].values()) #先切片再取值
print(users.values("name","password")) #name和password为models中定义的属性值,结果只返回这两个字段的值
也可以直接写values()
users=models.User.objects.values()
print(users)
指定要获取的数据字段
3、values_list() 获取字段的值,返回QuerySet对象,以列表嵌套元组的形式返回,每一个元组都是一个数据对象
∴ values和values_list不指定字段,返回所有字段的值;指定字段,仅返回指定字段的值
.query #对于QuerySet对象,可以用.query查看内部封装的sql语句
4.filter() 带条件过滤,查询符合条件的所有数据,返回的仍是QuerySet对象
相当于SQL中的where语句
语法格式: models.表名.objects.filter(条件)
没有符合条件的数据时,返回空对象<QuerySet [ ]>
如果想要查看对象具体的值,后面可以接values(),即返回该对象所有属性的值
users=models.User.objects.filter(id=1).values() #先过滤然后查询对象的值
5、取QuerySet对象中部分对象
①对于QuerySet对象索引取出object对象,索引还是从0开始,但是对象的下标都是从1开始
users=models.User.objects.filter(id=1)[0]
②.first(),取出查询结果QuerySet对象中的第一个元素
只能作用于QuerySet对象,返回object对象
语法格式: userobj=models.User.objects.filter(password=123456).first()
③.last(),取出查询结果QuerySet对象中的最后一个元素
只能作用于QuerySet对象,返回object对象
语法格式: userobj_last=models.表名.objects.filter(password=123456).last()
6、如果想要查看对象某个属性的值,必须是object对象调用属性
userobj_first=models.User.objects.filter(password=123456).first()
print(userobj_first.name) #name为对象的属性,直接查询
如果QuerySet对象直接调用属性,就会报错
【了解】get(),查询单一结果,返回的是数据对象,如果不存在会抛出模型类.DoesNotExist异常。
只需要记住filter用法就行了,可以加过滤条件,结果只能有一个,如果有多个,会报错;
也可以用于取object对象,且QuerySet结果对象中只有一个元素,但是这么用的话直接写first就好了
其他条件查询
1、distinct()去重查询某个字段的所有值
userobj=models.User.objects.values("password").distinct()#去重查找某个字段的所有值
userobj=models.User.objects.distinct().values("password")#这种写法也可以,distinct在前面
print(userobj,'\n',userobj.query) #实现了sql中的distinct功能
如果values中有多个字段,但必须多个属性都重复,才不会被消除掉
如果distinct属性主键 ,distinct住家米有效果
2、order_by()排序
res=models.User.objects.order_by("id").values("id")#升序
res1=models.User.objects.order_by("-id").values("id")#降序
3、reverse()反转
对已经排序过的进行反转,和反过来排布的结果一样,意义?
res1=models.User.objects.order_by("-id").reverse().values("id")
4、count()统计当前数据的个数,针对queryset对象
users=models.User.objects.count()
userobj_first=models.User.objects.filter(password=123456).count()
print(users,userobj_first)
5、exclude() 把。。。排除在外
users=models.User.objects.exclude(name='test').values()#查询所有name不是test的数据
双下划线条件查询
注意:这里修改了test中的main函数,User已引入,所以不需要写models了
1、{字段}__gt==num 查询字段大于num的所有数据
users=User.objects.filter(id__gt=5) #查询id>5的数据 ,不包含5
2、{字段}__gte==num 查询字段大于等于num的所有数据
users=User.objects.filter(id__gte=5).values() #查询id>=5的数据
3、{字段}__lt==num 查询字段小于num的所有数据
users=User.objects.filter(id__lt=5).values() #查询id<5的数据
4、{字段}__lte==num 查询字段小于等于num的所有数据
users=User.objects.filter(id__lte=5).values() #查询id<=5的数据
5、{字段}__in=[a,b,c] 查询字段的值是a或b或c的所有数据
就相当于SQL中的in
users=User.objects.filter(id__in=[1,3,5]).values()
6、{字段}__range=(10,20) 查询字段的值在10到20之间的,包含10和20
users=User.objects.filter(id__range=[1,4])
7、{字段}__contain=‘abc’ 查询字段值包含某些字符的所有数据
关键字区分大小写
users=User.objects.filter(name__contains='bb').values()
8、{字段}__icontains=‘abc’ 查询出字段值中包含指定字符的所有数据
关键字不区分大小写
9、{字段}__startswith=‘n’ 查询字段以指定字符开头的所有数据
users=User.objects.filter(name__startswith='b').values()
10、{字段}__endswith=‘n’ 查询字段以指定字符结果的所有数据
users=User.objects.filter(name__endswith='b').values()
附:
test.py中所有代码
from django.test import TestCase
#from myapp01 import models.User
import os
# Create your tests here.
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE','mydjangoProject.settings') #项目下的settings
import django
django.setup()
#from myapp01 import models 第一种引入方式
from myapp01.models import User
#print(users[1:4].values())
#以下是第一种引入方式,要写models.User.objects.xxx
'''users=models.User.objects.all()
users1=models.User.objects.values()# 直接查询出所有数据对象
print(users)
print(users.values()) #查询所有数据的值
# print(users[1:4].values()) #取部分值
#print(users.values("name","password")) #name和password为models中定义的属性值,结果只返回这两个字段的值
#print(users.values_list())
print(users.query)
res=users.values_list("name","password")
#print(res)
print(res.query) #查看内部封装的sql语句,只有queryset对象才能查看'''
#users=models.User.objects.filter(id=1) #过滤
#users=models.User.objects.filter(id=1).values() #先过滤然后查询对象的值
#users2=models.User.objects.all()[2] #用索引找对象,下标还是从0开始,对应的object对象下标从1开始
#users=models.User.objects.filter(id=1)[0] #索引从0开始
#userobj_first=models.User.objects.filter(password=123456).first()#取queryset对象中的第一个元素
#userobj_last=models.User.objects.filter(password=123456).last() #取queryset对象中的最后一个元素
#userobj=models.User.objects.values("password").distinct()#去重查找某个字段的所有值
#userobj=models.User.objects.distinct().values("name","password")#这种写法也可以,distinct在前面
#userobj_first=models.User.objects.filter(password=123456).first().name #name为对象的属性,直接查询
'''res=models.User.objects.order_by("name").values()#升序
res1=models.User.objects.order_by("-name").values()#降序
res=models.User.objects.order_by("id").values("id")#升序
res1=models.User.objects.order_by("-id").reverse().values("id")#反转'''
#users=models.User.objects.count() #统计queryset结果对象中的元素个数
#users=models.User.objects.exclude(name='test').values()# exclude,过滤掉满足条件的,相当于not或!=
#注意以下是User第二种引入方式
#users=User.objects.filter(id__gt=5).values() #查询id>5的数据
#users=User.objects.filter(id__gte=5).values() #查询id>=5的数据
#users=User.objects.filter(id__lte=5).values() #查询id<5的数据
#users=User.objects.filter(id__in=[1,3,5]).values() #查询id是 1或3或5的所有数据
#users=User.objects.filter(id__range=[1,4])
#users=User.objects.filter(name__startswith='b').values() #查询name以b开头的所有数据
#users=User.objects.filter(name__endswith='b').values() #查询name以b结尾的所有数据
users=User.objects.filter(name__endswith='b').values()
print(users)
modles.py中代码
from django.db import models
# Create your models here.
class User(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)