zoukankan      html  css  js  c++  java
  • 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__"
        
    从小白到大神的蜕变~~
  • 相关阅读:
    JavaScript
    94.Binary Tree Inorder Traversal
    144.Binary Tree Preorder Traversal
    106.Construct Binary Tree from Inorder and Postorder Traversal
    105.Construct Binary Tree from Preorder and Inorder Traversal
    90.Subsets II
    78.Subsets
    83.Merge Sorted Array
    80.Remove Duplicates from Sorted Array II
    79.Word Search
  • 原文地址:https://www.cnblogs.com/tjw-bk/p/13911156.html
Copyright © 2011-2022 走看看