day53 django 模型層

[TOC]python

模型層

ORM查詢

​ 如何配置測試腳本 ​ 第一種: ​ 直接在某一個應用下的tests文件中書寫下面內容,而後本身寫兩行mysql

#當你想單獨測試django中某個py文件,須要手動配置測試監本
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")
    import django
    django.setup()
    #必定要等待測試腳本搭建完畢以後,才能導入django文件進行測試
    from app01 import models

第二種 直接新建一個任意名稱的py文件,在裏面寫上配置git

#當你想單獨測試django中某個py文件,須要手動配置測試監本
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")
    import django
    django.setup()
    #必定要等待測試腳本搭建完畢以後,才能導入django文件進行測試
    from app01 import models

若是想查看QuerySet裏的SQL語句,在settings裏面加上sql

"""
    若是你想查看全部的orm語句內部對應的sql語句
    你能夠直接在配置文件中配置相應的代碼便可
 """
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

1.單表操做

建立一張表數據庫

class Books(models.Model):
    title=models.CharField(max_length=32)
   price=models.DecimalField(max_digits=8,decimal_places=2)
    publish_data=models.DateField()

建立數據

​ 1.create方法django

book_obj=models.Books.objects.create(title='西遊記',price=123.23,publish_data='2019-12-12')
    print(book_obj)
    from datetime import date
    ctime=date.today()
    book_obj=models.Books.objects.create(title='紅樓夢',price=888,publish_data=ctime)

2.利用對象的綁定方法json

book_obj=models.Books(title='水滸傳',price=56.33,publish_data='2000-1-21')
    book_obj.save()

修改數據

res=models.Books.objects.filter(pk=2)
    print(res)
    print(res.query) # SELECT `app01_books`.`id`, `app01_books`.`title`, `app01_books`.`price`, `app01_books`.`publish_data` FROM `app01_books` WHERE `app01_books`.`id` = 2
    '''
    pk會自動幫你查找到當前表的主鍵字段,後期會用pk來指代主鍵字段
    filter查詢出來的結果是QuerySet對象
        1.只要是QuerySet對象就能夠無限制的調用QuerySet的方法
            例如:fileter  create  delete 
            res=models.Books.objects.filter(pk=2).filter().filter()
        2.只要是QuerySet對象就能夠點query查看當前結果內部對應的sql語句'''
    #方式1:利用QuerySet方法
    models.Books.objects.filter(pk=2).update(price=333)
    #方式2:利用對象
    book_obj=models.Books.objects.get(pk=2)#該方法不推薦使用,推薦使用queryset方法
    book_obj.price=2222
    book_obj.save()
    #利用對象的修改,內部實際上是重頭到尾將數據的全部字段都重寫了一遍
    '''
    get和filter區別
    1.filter獲取的是一個QuerySet對象,相似於一個列表
    2.get獲取的是數據對象自己
    當條件不存在的狀況下:
        filter不報錯,直接返回一個空,推薦使用filter
        get會直接報錯,全部不推薦使用'''

刪除數據

#1.利用QuerySet方法  delete()
    models.Books.objects.filter(pk=3).delete()
    #2.對象方法
    book_obj=models.Books.objects.get(pk=2)
    book_obj.delete()

查數據 必知必會13條

1.all() 查詢全部 返回queryset對象
res=models.Books.objects.all()
    print(res)
     '''
    orm語句的查詢默認都是惰性查詢
    只有真正使用數據的時候纔會執行orm語句''
2.filter() 篩選 返回的是queryset對象
# 至關於你原生SQL語句裏面的where關鍵字
    res=models.Books.objects.filter(pk=5)#支持多個參數,而且是and關係
    print(res)
3.get() 篩選 獲取的數據對象自己
# 條件不存在直接報錯 而且查詢條件必須是惟一的
    res=models.Books.objects.get(pk=4)
    print(res)
4.first() 取queryset中第一個數據對象
res=models.Books.objects.filter(pk=4).first()
    print(res)
5.last() 取queryset中最後一個數據對象
res=models.Books.objects.filter(title='西遊記').last()
    print(res)
6.count()統計數據的個數 返回數字
num=models.Books.objects.count()
    print(num)
7.values() 獲取數據對象中指定的字段的值 queryset 列表套字典
#能夠拿多個                                      	  res=models.Books.objects.values('title','price')
print(res)
8.values_list() 獲取數據對象中指定的字段的值 queryset 列表套元組
#  能夠拿多個
res=models.Books.objects.values_list('title','price') res=models.Books.objects.filter(pk=5).values_list('title','price')
print(res)
9.order_by() 指定字段排序 返回queryset
res=models.Books.objects.order_by('price')#默認是升序
    res=models.Books.objects.all().order_by('price') #等價 語義更明確
    res = models.Books.objects.order_by('-price')#加負號 降序
    print(res)
10.reverse() 顛倒順序 返回queryset
# 前提是顛倒的對象必須有順序(提早排序以後才能顛倒)
    res = models.Books.objects.all().order_by('price')
    res=res.reverse()
    print(res)
11.exclude() 排除什麼什麼以外 返回queryset
res=models.Books.objects.all().exclude(title='西遊記')
    print(res)
12.exists() 判斷查詢結果是否有值 返回結果是一個布爾值
res=models.Books.objects.filter(pk=5).exists()
    print(res)
    # 該方法其實不須要使用,由於數據自己自帶布爾值
13.distinct() 查詢結果進行去重操做 返回queryset
# 前提:數據必須是要徹底相同的狀況下 才能去重(容易忽略主鍵)
  res=models.Books.objects.values_list('title','price').distinct()
    print(res)

2.神奇的雙下劃線查詢

#查詢價格大於500的書籍
    res=models.Books.objects.filter(price__gt=500)
    
    #查詢價格小於500的書籍
    res=models.Books.objects.filter(price__lt=500)
    
    #查詢價格大於等於500的書籍
    res=models.Books.objects.filter(price__gte=500)
    
    #查詢價格小於等於500的書籍
    res=models.Books.objects.filter(price__lte=500)
    
    #查詢價格是222或者444或者500的書籍
    res=models.Books.objects.filter(price__in=[222,444,500])
    
    #查詢價格在200到800之間的書籍
    res=models.Books.objects.filter(price__range=(200,800))
    
    #查詢出版日期是2019年的書籍
  res=models.Books.objects.filter(publish_data__year='2019')

    #查詢出版日期是1月份的書籍
   res=models.Books.objects.filter(publish_data__month='1')

    # 模糊查詢
    '''
    mysql中的模糊查詢
        關鍵字 like
            模糊匹配的符號
                %:匹配任何個數的任意字符
                _:匹配覺得任意字符'''
    #查看書籍是以西開頭的書
    res=models.Books.objects.filter(title__startswith='西')
    
    #查詢書籍是以記結尾的書
    res=models.Books.objects.filter(title__endswith='記')
    
    #查詢書籍名稱中包含遊字的書籍
    res=models.Books.objects.filter(title__contains='遊')
    
    #查詢書籍名稱包含字母p的書籍
    res=models.Books.objects.filter(title__contains='p')#默認區分大小寫
    res=models.Books.objects.filter(title__icontains='p')#忽略區分大小寫

3.圖書管理系統表設計

class Book(models.Model):
    title=models.CharField(max_length=32)
    price=models.DecimalField(max_digits=8,decimal_places=2)
    publish_data=models.DateField(auto_now_add=True)
    '''
    auto_now:每次修改數據的時候,都會更新修改數據時間(展現最新的依次修改時間)
    auto_now_add:當數據建立出來的時候,會自動將建立時間記錄下來
    '''
    publish=models.ForeignKey(to='Pbulish')
    author=models.ManyToManyField(to='Author')

class Pbulish(models.Model):
    name=models.CharField(max_length=32)
    addr=models.CharField(max_length=64)
    def __str__(self):
        return self.name

class Author(models.Model):
    name=models.CharField(max_length=64)
    email=models.EmailField()#對應到數據庫中僅僅是varchar(254),沒有任何限制條件,該字段只要是字符串就行
    #僅僅是爲了表達語義,如何限制:後期須要藉助於校驗性組件
    author_detail=models.OneToOneField(to='AuthorDetail')
    def __str__(self):
        return self.name

class AuthorDetail(models.Model):
    phone=models.BigIntegerField()
    addr=models.CharField(max_length=64)
    def __str__(self):
        return self.addr

4.外鍵字段(一對多)的增刪改查

#第一種
    models.Book.objects.create(title='西遊記',price=233,publish_id=1)
    # 直接傳表裏面的實際字段,跟數據主鍵值 publish_id
    
    #第二種
    publish_obj=models.Pbulish.objects.filter(pk=2).first()
    models.Book.objects.create(title='紅樓夢',price=555,publish=publish_obj)
    # 傳虛擬字段 跟數據對象便可
#第一種
    models.Book.objects.filter(pk=1).update(publish_id=2)
    #第二種
    publish_obj=models.Pbulish.objects.filter(pk=1).first()
  models.Book.objects.filter(pk=1).update(publish=publish_obj)
刪除
#默認就是級聯產出,級聯更新
    models.Pbulish.objects.filter(pk=1).delete()

5.外鍵字段(多對多)的增刪改查

book_obj=models.Book.objects.filter(pk=3).first()
    print(book_obj.publish)#點外鍵字段,可能會直接獲取到外鍵關聯的數據對象
    #給當前這本書綁定做者
    print(book_obj.author)#已經跨到第三張表
    book_obj.author.add(2)#在第三種表裏面給書籍綁定一個主鍵爲2的做者

    author_obj=models.Author.objects.filter(pk=1).first()
    author_obj1=models.Author.objects.filter(pk=2).first()
    book_obj.author.add(author_obj)
    book_obj.author.add(author_obj,author_obj1)
    '''
    add方法 可以朝第三張關係表添加數據
    既支持傳數字:add(1,2)
    也支持傳對象:add(author_obj,author_obj1)
    而且二者均可以傳多個'''
book_obj=models.Book.objects.filter(pk=3).first()
    book_obj.author.set((1,3))
    book_obj.author.set([1,])

    author_obj=models.Author.objects.filter(pk=1).first()
    author_obj1=models.Author.objects.filter(pk=2).first()
    book_obj.author.set((author_obj,author_obj1))
    '''
    set修改多對多關係表中的數據
    既能夠傳數字也能夠傳對象
    可是須要注意的是括號內必須是可迭代對象
    都支持多個
        set((1,3))
        set((author_obj,author_obj1))'''
book_obj=models.Book.objects.filter(pk=3).first()
    book_obj.author.remove(1,2)

    author_obj = models.Author.objects.filter(pk=1).first()
    author_obj1=models.Author.objects.filter(pk=2).first()
    book_obj.author.remove(author_obj)
    book_obj.author.remove(author_obj,author_obj1)
    '''
    remove既能夠傳數字,也能夠傳對象
    而且都支持多個,不須要迭代
    remove(1,2)
    remove(author_obj,author_obj1)'''
清空 刪除某個數據在第三張表中的全部記錄
book_obj=models.Book.objects.filter(pk=4).first()
    book_obj.author.clear()
    '''
    clear清空書籍相關全部記錄,括號內不須要傳遞參數'''

6.跨表查詢、

正反向查詢: 關係字段在誰那,由誰查,誰就是正向 若是關係字段不在,就是反向 正向查詢按字段,反向查詢按表名小寫+_setapp

基於對象的跨表查詢 子查詢 分佈操做
# 1.查詢書籍主鍵爲3的出版社名稱
    book_obj=models.Book.objects.filter(pk=3).first()
    print(book_obj.publish)
    print(book_obj.publish.name)
    #2.查詢書籍主鍵爲3的做者姓名
    book_obj=models.Book.objects.filter(pk=3).first()
    print(book_obj.author)
    print(book_obj.author.all())
    # print(book_obj.author.all().first().name)
    #3.查詢做者是Jason的手機號碼
    author_obj=models.Author.objects.filter(name='json').first()
    print(author_obj.author_detail)
    print(author_obj.author_detail.phone)
    '''
    何時須要加all:
        當正向查詢點擊外鍵字段數據有多個的狀況下 須要,all()
        app01.Author.None  一旦看到該結果 只須要加.all()便可'''
    #4查詢出版社是東方出版社出版過的書籍
    publish_obj=models.Pbulish.objects.filter(name='西方出版社').first()
    print(publish_obj.book_set)
    print(publish_obj.book_set.all())
    #5.查詢做者是Jason寫過的書籍
    author_obj=models.Author.objects.filter(name='json').first()
    print(author_obj.book_set)
    print(author_obj.book_set.all())
    #6.查詢手機號是1210的做者姓名
    author_detail_obj=models.AuthorDetail.objects.filter(phone=110110).first()
    print(author_detail_obj.author)
    '''
    何時反向查詢表名小寫須要加_set
    一對多  多對多
    一對一不須要加_set'''
基於雙下劃線的跨表查詢 聯表操做
#1.查詢書籍pk爲3的出版社名稱
    #正向:
    res=models.Book.objects.filter(pk=3).values('publish__name')
    #寫外鍵字段就至關於已經跨到外鍵字段所關聯的表
    #想要改表裏的那個字段信息,只需加__獲取便可
    #models後面點誰,誰就是基表
    print(res)
    res=models.Pbulish.objects.filter(book__pk=3).values('name')
    print(res)

    #2.查詢書籍pk爲3的做者姓名和郵箱
    #正向
    res=models.Book.objects.filter(pk=3).values('author__name','author__email')
    print(res)
    #反向
    res=models.Author.objects.filter(book__pk=3).values('name','email')
    print(res)

    #3.查詢做者是json的家庭地址
    #正向
    res=models.Author.objects.filter(name='json').values('author_detail__addr')
    print(res)
    #反向
    res=models.AuthorDetail.objects.filter(author__name='json').values('addr')
    print(res)

    #4.查詢出版社是西方出版社初設過得書的名字
    #反向
    res=models.Pbulish.objects.filter(name='西方出版社').values('book__title')
    print(res)
    #正向
    res=models.Book.objects.filter(publish__name='西方出版社').values('title')
    print(res)

    #5.查詢書籍pk是3的做者的手機號
    res=models.Book.objects.filter(pk=3).values('author__author_detail__phone')
    print(res)
    res=models.Author.objects.filter(book__pk=3).values('author_detail__phone')
    print(res)
相關文章
相關標籤/搜索