Django--model-資料庫操作
阿新 • • 發佈:2020-11-01
目錄
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__"