Django ORM 數據庫常用操作


Django是一個開放源代碼的Web應用框架,由Python寫成。采用了MTV的框架模式,即模型M,視圖V和模版T。它最初是被開發來用於管理勞倫斯出版集團旗下的一些以新聞內容為主的網站的,即是CMS(內容管理系統)軟件。並於2005年7月在BSD許可證下發布。這套框架是以比利時的吉普賽爵士吉他手Django Reinhardt來命名的。 -- 百度百科

設置數據庫字段映射

from django.db import models
import sqlite3

class User(models.Model):
    id = models.AutoField(primary_key=True)    # 設置ID字段(默認自增長)
    username = models.CharField(max_length=32) # 設置用戶名最大32個字符
    password = models.CharField(max_length=32) # 設置用戶密碼
    data = models.DateField()                  # 注冊日期
    # 設置最大5位數,其中小數點占用2位
    number = models.DecimalField(max_digits=5,decimal_places=2)

更新與遷移數據庫

python manage.py makemigrations   # 將你的數據庫變動記錄下來(並不會幫你創建表)
python manage.py migrate          # 將你的數據庫變動正在同步到數據庫中
python manage.py createsuperuser  # 創建一個超級用戶

ORM 數據添加與刪除

from django.shortcuts import render,HttpResponse
from MyWeb import models

def insert(request):
    # ---------------------------------------------------------------------
    # 添加表記錄,方式1
    models.User.objects.create(username="admin",password="123123",data="2019-01-01",number=3.1)
    models.User.objects.create(username="guest", password="123456", data="2019-02-12", number=2.1)
    models.User.objects.create(username="admin", password="123123", data="2019-02-12", number=2.1)
    models.User.objects.create(username="wangwu", password="rwqwe33", data="2018-02-12", number=4.1)
    models.User.objects.create(username="zhangsan", password="8888", data="2017-05-21", number=9.9)
    models.User.objects.create(username="lisi", password="99994", data="2010-2-11", number=8.1)

    # 添加表記錄,方式2
    dic = {"username":"wangermazi","password":"123321","data":"2019-12-12","number":2.15}
    models.User.objects.create(**dic)

    # 添加表記錄,方式3
    obj = models.User(username="lyshark",password="1233",data="2010-01-01",number=3.14)
    obj.save()

    # 添加表記錄,方式4
    obj = models.User()
    obj.username="django"
    obj.password="55555"
    obj.data="2003-01-12"
    obj.number="3.14"
    obj.save()

    # ---------------------------------------------------------------------
    # 更新數據的方式
    models.User.objects.filter(id=2).update(username="hello")
    # 第二種更新數據的方式
    obj = models.User.objects.get(id=2)
    obj.username="tomcat"
    obj.password="tomcat"
    obj.save()

    # ---------------------------------------------------------------------
    # 刪除數據的方式
    models.User.objects.filter(id=1).delete()    # 刪除id是1的一條數據
    models.User.objects.get(id=2).delete()       # 刪除id是2的一條數據
    models.User.objects.all().delete()           # 刪除所有數據

    return  HttpResponse("<h1>hello lyshark</h1>")

ORM 單表查詢操作

from django.shortcuts import render,HttpResponse
from MyWeb import models

def select(request):
    print(models.User.objects.all())                               # 獲取所有數據
    print(models.User.objects.count())                             # 獲取數據庫中的總共記錄數
    print(models.User.objects.filter(username="admin").count())    # 獲取admin這條記錄的數量

    print(models.User.objects.filter(username="lyshark"))          # 查詢username=lyshark的記錄
    print(models.User.objects.filter(id=1,username="admin"))       # 查詢ID=1且username=admin的記錄

    # 查詢用戶名是lyshark,並且拿到它的id與password字段數據
    print(models.User.objects.filter(username="lyshark").values("id","password"))
    # 查詢記錄中是lyshark的記錄,並且拿到它的id和password,且轉換成元組的形式返回
    print(models.User.objects.filter(username="lyshark").values_list("id","password"))

    print(models.User.objects.get(username="lyshark"))                   # 得到model對象
    print(models.User.objects.exclude(username="admin"))                 # 查詢所有用戶記錄,排除掉admin的記錄
    print(models.User.objects.filter(username="admin").exclude(id=3))    # 支持鏈式過濾,查找admin的記錄,排除掉id=3

    print(models.User.objects.all().order_by("id"))                # 查詢記錄並以id字段正向排序
    print(models.User.objects.all().order_by("-id"))               # 同樣可以實現反向排序
    print(models.User.objects.all().order_by("id").reverse())      # 查詢記錄並以id字段反向排序
    print(models.User.objects.filter(username="admin").values("username").distinct()) # 去重

    print(models.User.objects.all().first())                 # 查詢第一條記錄
    print(models.User.objects.all().last())                  # 查詢最后一條記錄

    print(models.User.objects.filter(id__lt=5,id__gt=1))     # 查詢ID小於5且大於1的數據
    print(models.User.objects.filter(id__in=[1,2,3]))        # 查詢ID等於1,2,3的行
    print(models.User.objects.filter(id__range=[1,100]))     # 查詢UD在1-100范圍內的行

    print(models.User.objects.filter(username__contains="ad").values_list())  # 模糊查詢(大小寫敏感)
    print(models.User.objects.filter(username__icontains="ad").values_list()) # 模糊查詢(大小寫不敏感)

    print(models.User.objects.all()[1:3])   # 查詢后切片,只取出1-3行元素
    print(models.User.objects.all()[2:9])   # 查詢切片,只取出2-9行元素

    return  HttpResponse("<h1>hello lyshark</h1>")

ORM 一對多的使用: 比如說一個出版社可以出版多本書,但是一本書只能夠在一個出版社進行發表,這就是一個典型的一對多的關系,一對多models.ForeignKey(),如下我們首先創建一個Book表,然后創建一個Publish表,一個Publish記錄中可以包含多本書.

from django.db import models
import sqlite3

class Book(models.Model):
    id = models.AutoField(primary_key=True)                     # 自增長的一個主鍵
    title = models.CharField(max_length=32)                     # 書籍名稱
    data = models.DateField()                                   # 出版日期
    price = models.DecimalField(max_digits=5,decimal_places=2)  # 一共5位保留兩位小數
    # 建立一對多關系,關聯到Publish表中,django會自動在publish_key后面加上_id
    publish_key = models.ForeignKey("Publish",on_delete=models.CASCADE)

class Publish(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)     # 出版社名字
    addr = models.CharField(max_length=32)     # 出版社地址
python manage.py makemigrations   # 將你的數據庫變動記錄下來(並不會幫你創建表)
python manage.py migrate          # 將你的數據庫變動正在同步到數據庫中

創建一對多關系

from django.shortcuts import render,HttpResponse
from MyWeb import models

def insert(request):
    # 首先創建兩個出版社名字
    models.Publish.objects.create(name="人民出版社",addr="中國 北京")
    models.Publish.objects.create(name="清華出版社",addr="北京 海淀")

    # 一對多關系的添加方式:第一種方式
    models.Book.objects.create(title="<Python從入門到入土>",data="2019-12-12",price=22,publish_key_id=1)
    models.Book.objects.create(title="<java 從入門到放棄>", data="2019-11-24", price=55, publish_key_id=1)
    models.Book.objects.create(title="<go 從閏土到入土>", data="2018-11-24", price=77, publish_key_id=1)

    # 一對多關系的添加方式:第二種添加方式(推薦)
    obj = models.Publish.objects.filter(name="清華出版社")[0]
    print("出版社ID號:{}".format(obj.id))
    models.Book.objects.create(title="<簡愛>",data="2019-01-01",price=45.5,publish_key_id=obj.id)
    models.Book.objects.create(title="<駱駝祥子>", data="2007-05-01", price=25.5, publish_key_id=obj.id)

    # 一對多關系的添加方式:第三種添加方式
    obj = models.Publish.objects.get(name="人民出版社")
    book = models.Book(title="<django 姜哥>",data="2014-01-02",price=22.6,publish_key_id=obj.id)
    book.save()
    
    return  HttpResponse("<h1>hello lyshark</h1>")

一對多的查詢

from django.shortcuts import render,HttpResponse
from MyWeb import models

def insert(request):
    # 普通查詢:查詢人民出版社出版過的所有書籍
    obj = models.Publish.objects.get(name="人民出版社")
    bookOBJ = obj.book_set.all()
    for item in bookOBJ:
        print("出版書籍:{} 出版日期:{} ".format(item.title,item.data))

    # 正向查詢:查詢<Python從入門到入土>這本書的出版社的地址
    bookOBJ = models.Book.objects.filter(title="<Python從入門到入土>")[0]
    print("書籍:{}  出版地址是:{}".format(bookOBJ.title,bookOBJ.publish_key.addr))

    # 反向查詢: 查詢人民出版社出版過的所有的書的價格和名字
    publishOBJ = models.Publish.objects.filter(name="人民出版社")[0]
    book_dic = publishOBJ.book_set.all().values('title','price')[0]
    print("書籍:{}  當前價格:{}".format(book_dic['title'],book_dic['price']))

    # 另一種查詢:查詢人民出版社出版過的所有書籍,並打印出價格 (高效查詢)
    ret = models.Publish.objects.filter(name="人民出版社").values("book__title","book__price")
    for i in range(0,len(ret)):
        print("出版書籍: {}  當前價格:{} ".format(ret[i]['book__title'],ret[i]['book__price']))

    # 第二種查詢方式(該方法更簡單)
    ret = models.Publish.objects.filter(name="人民出版社").values("book__title","book__price")
    for i in ret:
        print("出版書籍: {}  當前價格:{} ".format(i['book__title'], i['book__price']))

    return  HttpResponse("<h1>hello lyshark</h1>")

ORM 多對多的使用: 一個作者可以寫多本書,同樣的一本書可能是由多個作者一起寫出來的,這就是多對多的關系,多對多models.ManyToManyField()

from django.db import models
import sqlite3

class Book(models.Model):
    id = models.AutoField(primary_key=True)                     # 自增長的一個主鍵
    title = models.CharField(max_length=32)                     # 書籍名稱
    data = models.DateField()                                   # 出版日期
    price = models.DecimalField(max_digits=5,decimal_places=2)  # 一共5位保留兩位小數
    # 建立一對多關系,關聯到Publish表中,django會自動在publish_key后面加上_id
    publish_key = models.ForeignKey("Publish",on_delete=models.CASCADE)

    # 多對多,django會自動創建一個新的表book_author用來記錄多對多鍵值對
    author = models.ManyToManyField("Author")

class Publish(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)     # 出版社名字
    addr = models.CharField(max_length=32)     # 出版社地址

class Author(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)     # 作者姓名
    age = models.IntegerField()                # 作者年齡

多對多的數據創建操作技巧

from django.shortcuts import render,HttpResponse
from MyWeb import models

def insert(request):
    # 我們來創建幾個書籍作者
    models.Author.objects.create(name="張三", age=22)
    models.Author.objects.create(name="李四", age=33)
    models.Author.objects.create(name="王五", age=67)
    models.Author.objects.create(name="老王", age=87)
    models.Author.objects.create(name="小張", age=43)

    # -----------------------------------------------------------------------------
    # 拿到一個出版社的對象,我們這本《魯迅散文》是清華出版社的
    PublishOBJ = models.Publish.objects.filter(name="清華出版社")[0]
    # 接着我們創建一本書,並關聯一對多的關系(清華出版社->魯迅散文)
    BookObj = models.Book.objects.create(title="<魯迅散文>",data="2019-01-23",price=34.5,publish_key=PublishOBJ)
    # 接着我們取出本書的作者:比如本書是由張三,李四,老王寫出來的.
    zhangsan = models.Author.objects.filter(name="張三")[0]
    lisi = models.Author.objects.filter(name="李四")[0]
    laowang = models.Author.objects.filter(name="老王")[0]
    # 最后我們將這本<魯迅散文>與這三個作者關聯起來
    BookObj.author.add(zhangsan,lisi,laowang)

多對多的查詢

from django.shortcuts import render,HttpResponse
from MyWeb import models

def insert(request):
    # 正向查詢:查詢<魯迅散文>這本書是由那幾個人寫的,並打印出他的年齡
    BookOBJ = models.Book.objects.filter(title="<魯迅散文>")[0]
    name = BookOBJ.author.all().values("name")
    age = BookOBJ.author.all().values("age")
    for i in range(0,len(name)):
        print("書籍作者: {}".format(name[i]['name']))

    # 反向查詢:查詢李四這個作者寫過那幾本書
    lisi = models.Author.objects.filter(name="李四")[0]
    print("該作者寫過: "+ lisi.book_set.all().first().title)

    # 查詢人民出版社出版過的所有書籍
    publish = models.Publish.objects.get(name="人民出版社")
    booklist = publish.book_set.all()
    for i in range(0,len(booklist)):
        print("查詢到人民出版社,出版過: {}".format(booklist[i].title))

    # 另外一種查詢方式:查詢張三這個人寫過的書
    ret = models.Author.objects.filter(name="張三").values("book__title")
    print(ret)

    return HttpResponse("hello lyshark")

ORM 聚合查詢與分組查詢

from django.db.models import Avg,Sum,Count,Max,Min

def insert(request):
    # 查詢所有圖書的平均價格
    print(models.Book.objects.all().aggregate(Avg("price")))
    # 另一種自定義命名查詢
    print(models.Book.objects.all().aggregate(avg = Avg("price")))
    # 如果你希望生成不止一個聚合,可以這樣寫
    print(models.Book.objects.all().aggregate(avg=Avg("price"),max=Max("price"),min=Min("price")))

    # 查詢出,每本書的作者的總個數
    #print(models.Book.objects.all().annotate(num=Count("author__name")).values("num"))
    bookOBJ = models.Book.objects.all().annotate(num=Count("author__name"))
    for item in bookOBJ:
        print("書籍:{}  作者數量:{}".format(item.title,item.num))

    # 統計出每個出版社出版過最便宜的書的價格(方式1)
    print(models.Publish.objects.all().annotate(MinBook=Min("book__price")).values("name","MinBook"))

    # 統計出每個出版社出版過最貴的書的價格(方式2)
    publishOBJ = models.Publish.objects.annotate(MaxBook=Max("book__price"))
    for item in publishOBJ:
        print("出版社:{}  最貴的書:{}".format(item.name,item.MaxBook))

    # 統計出書籍名稱以<魯迅開頭的書籍,是由幾個作者寫的
    print(models.Book.objects.filter(title__startswith="<魯迅").annotate(Num=Count("author__name")).values("Num"))
    bookOBJ = models.Book.objects.filter(title__startswith="<魯迅").annotate(Num=Count("author__name"))
    for item in bookOBJ:
        print("書籍:{}  由{}個作者共同完成".format(item.title,item.Num))

    # 統計不止兩個作者的圖書,並打印出圖書的名字
    print(models.Book.objects.annotate(num=Count("author__name")).filter(num__gt=2).values("title","num"))

    # 根據一本圖書作者數量的多少對查詢集QuerySet進行排序
    print(models.Book.objects.all().annotate(num=Count("author__name")).order_by("num"))

    # 查詢每個作者出過的書的總價格,每個作者出過書之和
    print(models.Author.objects.all().annotate(PriceSum=Sum("book__price")).values("name","PriceSum"))

    return HttpResponse("hello lyshark")

ORM Django之F查詢與Q查詢

from django.db.models import F,Q

def select(request):
    # ---------------------------------------------------------------
    # F查詢:專門針對對象中某列中的某個值進行操作

    # 需求:通過F查詢我們將book表中所有圖書的價格全部漲價20元
    # F查詢:作用是取出 price 字段的值,然后進行 +20 的操作
    models.Book.objects.all().update(price=F("price") + 20)
    # 查詢評論數大於收藏數2倍的書籍
    models.Book.objects.filter(commnetNum__lt=F('keepNum') * 2)
    # 查看評論數大於閱讀數的書
    print(models.Book.objects.filter(commentNum__gt=F("readNum")))

    # ---------------------------------------------------------------
    # Q查詢: 用於應對更加復雜的查詢需求,例如使用and或or進行的復雜查詢.

    # Q查詢(單條件查詢): 查詢book表中,id=1的書,並打印出它的title字段.
    print(models.Book.objects.filter(Q(id=1)).values("title"))
    # Q查詢(多條件查詢):查詢book表中,id=1並且title=<Python從入門到入土> 查到后打印出price價格.
    print(models.Book.objects.filter(Q(id=1) & Q(title="<Python從入門到入土>")).values("price"))

    # Q查詢(跨表查詢):查詢author__name=張三的人寫過的書,並打印出title
    print(models.Book.objects.filter(Q(author__name="張三")).values("title"))


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM