1. 程式人生 > 實用技巧 >Django--model-資料庫操作

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
              })
      

      多對多序列化

      • 第一種方法
      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.ModelSerializer):
          # 欄位名,必須是模型可以引用到的變數
          # User(),Role 才能作為欄位名,如果是集合 需要many=True  
          user_set = UserSerializers(many=True)   # 新增顯示學生欄位
      
          class Meta:
              model = Role
              fields = "__all__"