• 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__"
        
    从小白到大神的蜕变~~
  • 相关阅读:
    对我影响最大的三位导师
    global与nonlocal
    random模块
    time模块
    datetime模块
    sys模块
    os模块
    collection模块
    hashlib模块
    pickle模块
  • 原文地址:https://www.cnblogs.com/tjw-bk/p/13911156.html
Copyright © 2020-2023  润新知