Loading

Django--model-数据库操作

https://www.cnblogs.com/xiaonq/p/10959010.html#i2

https://www.cnblogs.com/wupeiqi/articles/5246483.html

一、操作数据库表


1.基础操作

数据的增加

方法一:
#使用create方法添加数据 
user = User.objects.create(name='root', age=12, home='北京市', class_room_id=1)
方法二:
#使用save保存数据
obj = User(name='root', age=13, home='北京市', class_room_id=1)
obj.save()
方法三:
#传入多条数据需要添加**号 类似于*args,**kwargs
dic = {'name':'root', 'age':12, 'home':'北京市', 'class_room_id':1}
usesr=User.objects.create(**dic)

数据的删除

方法一:
#一般都是从前端获取到对应数据id/pk进行对应删除
user = User.objects.get(id=17).delete()
方法二:
user=User.objects.all().delete()  # 删除所有
方法三:
user=User.objects.filter(name='seven').delete() # 删除指定条件的数据

数据的修改

方法一:
user = User.objects.get(name='王五') #找到要修改的数据 一般使用id来查找 主键唯一
user.name = '猪悟能'			 #定义修改的数据
user.save()
方法二:
User.objects.all().update(age=12) #将所有用户的年纪修改成12
方法三:
# 将指定条件的数据更新,均支持 **kwargs 会修改所有的home字段都会修改成0
models.Tb1.objects.filter(name='root').update(home='0')
obj = models.Tb1.objects.get(id=1)
obj.c1 = '111'
obj.save()   
方法四:
obj = User.objects.get(id=16)
print(obj)
obj.c1 = '111' #c1 可以重写为obj的字段
obj.save()

数据的查询

方法一:
user=User.objects.get(id=1)       # 获取单条数据,不存在则报错(不建议)
#报错信息:User matching query does not exist.
方法二:
# 查询多个结果,有多少返回多少,不存在返回None 获取的数据是QuerySet 需要序列化
user = User.objects.all()  
方法三:
#获取指定条件的数据获取的数据是QuerySet 需要序列化
user = User.objects.filter(name='田七')  
#<QuerySet [<User: 田七>, <User: 田七>]>
方法四:
models.tb.objects.all().first()       #获取全部数据的第1条数据
方法五:
user=User.objects.filter(name='田七', class_room_id=1)  # 2个参数,获取指定条件的数据
#<QuerySet [<User: 田七>]>
方法六:
dic = {'name':'seven','password':'123'}  
models.tb.objects.filter(**dic)       #参数可以是字典形式,获取指定条件的数据
方法七:
dic = {'name':'田七', 'class_room_id':1}
user = User.objects.filter(**dic)  # 参数可以是字典形式,获取指定条件的数据
#<QuerySet [<User: 田七>]>
正向查找
# from . import models 
print(models.User.objects.get(name='111').class_room.classroom)  # 查找学生111所在的班级
# 2001B

print(models.User.objects.filter(class_room=1))  # 查询class_room为1班级所有学生
#<QuerySet [<User: 猪悟能>, <User: 沙僧>, <User: 李四>
反向查找
ClassRoom.user_set.all()   表名_set.all()
# 查询1910E班级所有学生
print(models.ClassRoom.objects.get(classroom='1910E').user_set.all())  
#<QuerySet [<User: 猪悟能>, <User: 李四>, <User: 李四>, <User: 田七>]>

2、进阶操作(了不起的双下划线)


其他不常用的操作看:https://www.cnblogs.com/wupeiqi/articles/5246483.html

利用双下划线将字段和对应的操作连接起来

获取个数
models.Tb1.objects.filter(name='田七').count() 	# 2
比较查询

gt      大于

gte     大于等于

lt      小于

lte     小于等于

exclude   不等于

#字段名__gt 比如:age__gt 
#字段名__lt 比如:age__lt 
models.User.objects.filter(id__gt=1)			 # 获取id大于1的值
models.User1.objects.filter(id__gte=1)			 # 获取id大于等于1的值
models.User.objects.filter(id__lt=10)	   		 # 获取id小于10的值
models.User.objects.filter(id__lte=10)           # 获取id小于10的值
models.User.objects.filter(id__lt=10, id__gt=1)	  # 获取id大于1 且 小于10的值

#<QuerySet [<User: 猪悟能>, <User: 猪悟能>, <User: 沙僧>, <User: 李四>
范围查询 :

in 在范围内

#字段名__in 比如:age__in 
models.User.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
models.User.objects.exclude(id__in=[11, 22, 33])  # not in 不在

#<QuerySet [<User: root>]>

range  相当于between...and...

#字段名__rang 比如:age__rang
models.User.objects.filter(id__range=[10,12]) #查询范围为10-12的id
#<QuerySet [<User: 田七>, <User: root>, <User: root>]>
空查询

isnull 是否为空

#字段名__isnull 比如:role__isnull
prin(models.User.objects.filter(role__isnull=Flast)) #输出role字段所有不为空的数据
print(models.User.objects.filter(role__isnull=True)) #输出role字段所有为空的数据
#<QuerySet [<User: 猪悟能>, <User: 沙僧>, <User: 李四>
模糊查询

contains 是否包含

#字段名__contains  比如:name__contains 
models.User.objects.filter(name__contains='r') #查询结果包含‘r’的

startswith,endswith 以指定值开头或结尾

istartswith iendswith 以指定值开头或结尾

#字段名__startswith  比如:name__startswith 
#字段名__endswith   比如:name__endswith 
models.User.objects.filter(name__startswith='李') #查询结果以‘李’开头的数据
#<QuerySet [<User: 李四>, <User: 李四>, <User: 李四>, <User: 李四>]>
models.User.objects.filter(name__endswith='能')	#查询结果以‘能’结尾的数据
#<QuerySet [<User: 猪悟能>, <User: 猪悟能>]>
日期查询

year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算。

User.objects.filter(pub_date__year=2005)
user.objects.filter(pub_date__year__gte=2005)
regex正则匹配,iregex 不区分大小写
Entry.objects.get(title__regex=r'^(An?|The) +')
Entry.objects.get(title__iregex=r'^(an?|the) +')
聚合函数

使用aggregate()过滤器调用聚合函数。聚合函数包括:Avg 平均,Count 数量,Max 最大,Min 最小,Sum 求和

from django.db.models import Sum,Avg,Count,Max,Min  #导包
user = models.User.objects.aggregate(Sum('age')) #求age的总和
#{'age__sum': 279}
F对象和Q对象

比较两个字段对象之间的关系用F对象。(F对象可以进行运算)

from django.db.models import F,Q
user = User.objects.filter(age__gte=F('age')) #查询年龄等于年龄的对象

#可以搭配+ - * /运算符
user=User.objects.update(age=F('age') + 2) #会把数据库中的age字段每个都加2

与逻辑运算符连用使用Q对象。 或( | ) 与( & )  非( ~ )

from django.db.models import F,Q
user = User.objects.filter(Q(age=12) | Q(name='root')) #查找age为12的数据或name为root的数据
#<QuerySet [<User: root>, <User: root>, <User: root>, <User: root>]>
排序

使用order_by对结果进行排序

user=User.objects.all().order_by('age')   #按年龄的升序排列

user=User.objects.all().order_by('-age')   #按年龄的降序排列
连表操作(关联查询)

利用双下划线和 _set 将表之间的操作连接起来

  • 一对一操作
user = models.User.objects.filter(id=2).first() #查询user表中id为2的数据
#查询id为2的数据的各种字段值
print(user.name)
print(user.age)
print(user.home)
print(user.role)
print(user.class_room_id)

#查询id为2的数据的name age字段值
user = models.User.objects.filter(id=2).values('name', 'age').first()
print(user)
print(user.keys())
print(user.values())
#{'name': '猪悟能', 'age': 17}
#dict_keys(['name', 'age'])
#dict_values(['猪悟能', 17])
  • 一对多操作

    • 类似一对一
    • 1、搜索条件使用 __ 连接 (适用于一表向多表查询数据)
    #查询classRoom表id=1的user学生
    classInfo=ClassRoom.objects.get(id=1)
    #使用模型类名称_set
    users=classInfo.user_set.all() #查询班级表对应的所有学生 数据一般会有很多 搭配序列化 
    
    • 2、获取值时使用 . 连接 (适用于多表向一表查询数据)
    #根据查询user表的数据.外键名.要查询的外键表里面的字段
    user=models.User.objects.filter(id=2).first()
    data=user.class_room.classroom #查询id为2的学生在哪个班级
    print(data)
    #得出数据 2001B
    
    • 还有一种是在建立模型类的时候使用related_name来指定变量名。
    # model.py
    hbook= model.ForeignKey(HeroInfo,on_delete=model.CACADE,null=Ture,related_name='heros')
    
  • 多对多操作

    • 1、建多对多表
    #model.py
    class Student(models.Model):
        name = models.CharField(max_length=32)
    
        # 老师类
    class Teacher(models.Model):
        name = models.CharField(max_length=32)
    	##让django帮助建立多对多关系表
        stu = models.ManyToManyField(to='Student',related_name='teacher')   
    
    • 2、数据的增删改查

    • 多对多数据添加使用 add

    • 多对多数据删除使用 remove

    • 多对多数据修改使用 模型类名称__set

    • 多对多数据获取使用 模型类名称__set

      user = models.ClassRoom.objects.get(classroom='2001B') #查询班级为2001B的班级
      user_info_objs = models.ClassRoom.objects.all() #查询所有班级
      
       
      # 添加数据
      #group_obj.user_info.add(user_info_obj)
      #group_obj.user_info.add(*user_info_objs)
       
      # 删除数据
      #group_obj.user_info.remove(user_info_obj)
      #group_obj.user_info.remove(*user_info_objs)
       
      
      # 获取数据
      #print user_info_obj.usergroup_set.all()
      #print user_info_obj.usergroup_set.all().filter(caption='CEO')
      #print user_info_obj.usergroup_set.all().filter(caption='DBA')
      

      views.py

      class ManyToManyTest(APIView):
      
          def get(self, request):
              # 方法一:在建立manytomany的models里查数据
              # teacherobj = models.Teacher.objects.get(id=2)
              # data = teacherobj.stu.all()
              # data_list = []
              # for i in data:
              #     data_dic={
              #         "student_name":i.name,
              #         "teacher_name":teacherobj.name
              #     }
              #     data_list.append(data_dic)
              # return Response(data_list)
      
              # 方法二:在未建立manytomany的models里查数据
              studentobj = models.Student.objects.get(id=2)
              data = studentobj.teacher_set.all()
              data_list = []
              for i in data:
                  data_dic = {
                      "student_name": studentobj.name,
                      "teacher_name": i.name
                  }
                  data_list.append(data_dic)
              return Response(data_list)
      
      
      
          def post(self, request):
      
              # 方法一:在建立manytomany的models里添加数据,(一条,一个对象)
              # teacherobj = models.Teacher.objects.filter(id=1).first()
              # studentobj = models.Student.objects.filter(id=2).first()
              # teacherobj.stu.add(studentobj)
              # return Response({
              #     "status": 200
              # })
      
              #方法二:在未建立manytomany的models里添加数据,(一条,一个对象)
              teacherobj = models.Teacher.objects.all()
              studentobj = models.Student.objects.filter(id=2).first()
              studentobj.teacher_set.set(teacherobj)
              return Response({
                  "status": 200
              })
      
          def put(self, request):
      
              # 方法一:在建立manytomany的models里修改数据,参数只能是可迭代对象
              teacherobj = models.Teacher.objects.filter(id=3).first()
              studentobj = models.Student.objects.filter(id=2)
              teacherobj.stu.set(studentobj)
              return Response({
                  "status": 200
              })
      
              #方法二:在未建立manytomany的models里修改数据,参数只能是可迭代对象
              # teacherobj = models.Teacher.objects.all()
              # studentobj = models.Student.objects.filter(id=2).first()
              # studentobj.teacher_set.set(teacherobj)
              # return Response({
              #     "status": 200
              # })
      
          def delete(self, request):
      
              # 方法一:在建立manytomany的models里删除数据,(一条,一个对象)
              # teacherobj = models.Teacher.objects.filter(id=1).first()
              # studentobj = models.Student.objects.filter(id=2).first()
              # teacherobj.stu.remove(studentobj)
              # return Response({
              #     "status": 200
              # })
      
              #方法二:在未建立manytomany的models里删除数据,(多条,可迭代对象)
              teacherobj = models.Teacher.objects.all()
              studentobj = models.Student.objects.filter(id=2).first()
              studentobj.teacher_set.remove(*teacherobj)
              return Response({
                  "status": 200
              })
      

      多对多序列化

      使用序列化器来进行查询展示的时候

      在多对多的模型类中,直接继承modelserializer,指定depth即可(第一种方法)、

      在未存在多对多的模型类里,继承seriizer,模型类_set指定一个序列化器(第二种方法)

      • 第一种方法
      from rest_framework import serializers
      from .models import *
      
      class UserSerializers(serializers.ModelSerializer):
          class Meta:
              model = User
              fields = "__all__"
              # fields=('name','age','role') #序列化时显示那些字典
              depth = 1  # 外键序列化
      
      • 第二种
      class UserSerializers(serializers.ModelSerializer):
          class Meta:
              model = User
              fields = "__all__"
              # fields=('name','age','role') #序列化时显示那些字典
              # depth = 1  # 外键序列化
      
      
      class RoleSer(serializers.Serializer):
          # 字段名,必须是模型可以引用到的变量
          # User(),Role 才能作为字段名,如果是集合 需要many=True  
          user_set = UserSerializers(many=True)   # 添加显示学生字段
      
          class Meta:
              model = Role
              fields = "__all__"
      
posted @ 2020-11-01 20:47  就学45分钟  阅读(73)  评论(0编辑  收藏  举报