一 、查詢
1、一對多
執行個體一(正向,用字段):
# 查詢紅樓夢的出版社名稱
#方式1:
ret=Book.objects.filter(title="紅樓夢").values("publish__name")
print(ret)
# <QuerySet [{'publish__name': '北京出版社'}]>
# 方式2:
res=Publish.objects.filter(book__title="紅樓夢").values("name")
print(res)
#<QuerySet [{'name': '北京出版社'}]>
執行個體二(反向,用表名):
# 查詢沙河出版社出版過的書籍名稱
#方式1:
ret=Publish.objects.filter(name="沙河出版社").values("book__title")
print(ret)
#<QuerySet [{'book__title': '金品梅2'}, {'book__title': '金品梅3'}]>
#方式2:
res=Book.objects.filter(publish__name="沙河出版社").values("title")
print(res)
#<QuerySet [{'title': '金品梅2'}, {'title': '金品梅3'}]>
2、多對多
# 查詢紅樓夢所有作者的名字
ret=Book.objects.filter(title="紅樓夢").values("authors__name")
print(ret)
#<QuerySet [{'authors__name': 'alex'}, {'authors__name': 'egon'}]>
#查詢alex出版過的所有書籍
ret=Author.objects.filter(name="alex").values("book__title")
print(ret)
#<QuerySet [{'book__title': '金品梅2'}, {'book__title': '紅樓夢'}]>
3、一對一
# 查詢位址在沙河并且email是123的作者的名字
ret=AuthorDetail.objects.filter(adrr="沙河",email=123).values("author__name")
print(ret)
#<QuerySet [{'author__name': 'alex'}]>
# 查詢alex作者的adrr位址
ret = Author.objects.filter(name="alex").values("authordetail__adrr")
print(ret)
#<QuerySet [{'authordetail__adrr': '沙河'}]>
執行個體三(綜合執行個體):
#email以456開頭的作者出版過的所有書籍名稱以及出版社名稱 ret=Book.objects.filter(authors__authordetail__email__startswith="456").values("title","publish__name")
print(ret)
總結,在上一章的對象查詢中,我們可以總結為所有的查詢是基于一個models對象,而本節中雙下劃線查詢均是基于queryset對象進行的!反向查詢使用的表名同樣必須為小寫。
二、聚合函數(aggregate)
aggregate()
是
QuerySet
的一個終止子句,意思是說,它傳回一個包含一些鍵值對的字典。鍵的名稱是聚合值的辨別符,值是計算出來的聚合值。鍵的名稱是按照字段和聚合函數的名稱自動生成出來的。如果你想要為聚合值指定一個名稱,可以向聚合子句提供它。如下例:
#查詢所有書籍的平均價格
# 執行個體1:
ret=Book.objects.all().aggregate(Avg("price"))
print(ret)
#{'price__avg': 172.66666666666666}
# 執行個體2:
res = Book.objects.all().aggregate(avgPrice=Avg("price"))
print(res)
#{'avgPrice': 172.66666666666666}
如果你希望生成不止一個聚合,你可以向
aggregate()
子句中添加另一個參數。是以,如果你也想知道所有圖書價格的最大值和最小值,可以這樣查詢:
# 查詢所有書籍的平均價格、價格最大值、價格最小值
ret = Book.objects.all().aggregate(Avg("price"),Min("price"),Max("price"))
print(ret)
#{'price__avg': 172.66666666666666, 'price__min': Decimal('123.00'), 'price__max': Decimal('230.00')}
以上執行個體中需要按照如下方式引入相應的子產品方法:
``from
django.db.models ``import
Avg, ``Max``, ``Min
三、分組函數(annotate)
annotate()為調用的
QuerySet
中每一個對象都生成一個獨立的統計值(統計方法用聚合函數)。
執行個體1:查詢每一個出版社出版過的書籍個數
ret=Publish.objects.all().annotate(num=Count("book__title")) #可以了解為每一個出版社對象增加一個num字段,該字段值是通過聚合函數聯表求得
for pub_obj in ret:
print(pub_obj.name,pub_obj.num)
annotate的傳回值是querySet,如果不想周遊對象,可以用上values_list,如下:
ret = Publish.objects.all().annotate(num=Count("book__title")).values_list("name","num")
print(ret)
#<QuerySet [('人民出版社', 0), ('沙河出版社', 2), ('北京出版社', 1)]>
執行個體2:查詢每一本書的作者個數
ret=Book.objects.all().annotate(counts=Count("authors__nid")).values("title","counts")
print(ret)
#<QuerySet [{'title': '金品梅2', 'counts': 2}, {'title': '金品梅3', 'counts': 2}, {'title': '紅樓夢', 'counts': 2}]>
二、方法
python生成requirements.txt項目依賴環境
進入python 項目目錄下,執行指令
pip freeze > requirements.txt
生成的requirements.txt 裡面就記錄了目前所有已經安裝的依賴包以及版本号
然後将生成的requirements.txt 拷貝到需要安裝同樣依賴環境的伺服器上
最後執行指令
pip install -r requirements.txt
就可以将所有依賴一次安裝完成
django中所有的指令
下載下傳django
pip install django==1.11.25 -i 源
建立django項目
django-admin startproject 項目名
啟動項目
切換到項目目錄下
python manage.py runserver # 127.0.0.1:8000
python manage.py runserver 80 # 127.0.0.1:80
python manage.py runserver 0.0.0.0::80 # 0.0.0.0::80
建立app
python manage.py startapp app名稱
資料庫遷移的指令
python manage.py makemigrations # 檢測已經注冊app下的models變更記錄
python manage.py migrate # 将變更記錄同步到資料庫中
request
request.POST # POST送出的資料 {} urlencode編碼
request.GET # url上攜帶的參數 ?id=1 {id:1}
request.method # 請求方法 GET POST
request.path_info # 路徑資訊 不包含IP和端口 也不包含查詢參數
request.FILES # 上傳的檔案 enctype='form-data'
request.session # {} session
request.COOKIES # cookie
request.META # 請求頭的資訊 HTTP_ 小寫——》 大寫 - ——》 _
request.body # 請求體 原始資料
request.get_full_path() # 完整的路徑資訊 不包含IP和端口 包含查詢參數
request.is_ajax() # 是否是ajax請求
request.get_signed_cookie(key,salt,defalut='')
response
HttpResponse('字元串') # 字元串
JsonResponse({}) JsonResponse([],safe=False)
render(request,'模闆檔案的路徑',{}) # 傳回頁面 已經替換好了
redirect('位址或者URLname') # 重定向 響應頭Location:位址 301 302
TemplateResponse(request,'模闆檔案的路徑',{}) # 後續在調用render方式進行渲染
ORM
正向查詢
有關聯關系的哪一方成為正向--也就是多的哪一方 -- 屬性查詢
反向查詢
沒有關聯關系的哪一方成為反向--也就是一的哪一方 -- 表名小寫
正向和反向查詢
正向 ----> 關聯字段在目前表中,從目前表向外查叫正向
反向 —> 關聯字段不在目前表中,當目前表向外查叫反向
正向通過字段,反向通過表名查
一對一 OneToOneField
# 一個文章詳情表一對一關聯文章表,相當于Foreignkey 加unique
class Article(models.Model):
nid = models.AutoField(primary_key=True)
desc = models.CharField(max_length=255)
class ArticleDetail(models.Model):
"""
文章詳情表
"""
nid = models.AutoField(primary_key=True)
content = models.TextField()
article = models.OneToOneField(to="Article", to_field="nid",on_delete=models.DO_NOTHING)
正向:
1、基于對象:obj.(外鍵).屬性
ArticleDetail_obj = models.ArticleDetail.objects.filter(pk=pk).first()
ArticleDetail_obj.article.desc
2、基于字段跨表查詢:外鍵__屬性
models.ArticleDetail.objects.filter(pk=2).values("article__desc")
反向:從詳情查文章
1、基于對象:obj.(表名小寫).屬性
article_obj = models.Article.objects.filter(pk=pk).first()
article_obj.articledetail.content
2、基于字段跨表查詢:表名小寫__屬性
models.Article.objects.filter(id=1).values('articledetail__content')
一對多 ForeignKey
book – > publish :一個出版社有多個書
class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=32)
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField( max_length=32)
# 與Publish建立一對多的關系
publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
1、基于字段:obj.(外鍵).屬性
book_obj = models.Book.objects.filter(title='紅樓夢').first()
book_obj.publish.name
反向:obj.(表名小寫_set).all()
1、set查詢
publish_obj=models.Publish.objects.filter(name="教育").first()
books = publish_obj.book_set.all()
for book in books:
print(book.title)
多對多 ManyToManyField
class Author(models.Model):
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=32)
age=models.IntegerField()
# 與AuthorDetail建立一對一的關系
authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE)
class Author(models.Model):
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=32)
age=models.IntegerField()
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
# 與Author表建立多對多的關系,ManyToManyField可以建在兩個模型中的任意一個,自動建立第三張表
authors=models.ManyToManyField(to='Author',)
1、基于字段:obj.(外鍵).all()
book_obj = models.Book.objects.filter(title="python教程").first()
authors = book_obj.authors.all()
for author in authors:
print(author.name,author.age)
author_obj = models.Author.objects.filter(name="moke").first()
books = author_obj.book_set.all()
for book in books:
print(book.title)
2、related_name查詢
author_obj.related_name.all()
常用字段
AutoField 自增 primary_key = True主鍵
IntegerField 整形 -21億 - 21億
BooleanField 布爾值類型
NullBooleanField 可以為空的布爾值
CharField 字元串
TextField 文本類型
DateTimeField 日期+加時間
DateField 日期格式
TimeField 時間格式
FloatField 浮點型
DecimalField(max_difits=6,decimal_piaces=3) 十進制小數
字段參數
null = True 資料庫中該字段可以為空
black = True 使用者輸入可以為空
default 預設值
db_index=True 索引
unique 唯一限制
verbose_name 顯示的名稱
choices 可選擇的參數
必知必會十三條
傳回對象清單 QuerySet
all() 所有的對象
filter() 擷取滿足條件的所有對象
exclude() 擷取不滿足條件的所有對象
order_by() 排序 -
reverse() 反轉
values() [ {} ]
values_list() [ () ]
distinct() 去重 不能按照字段去重
傳回對象
get() 擷取有且唯一的對象
first()
last()
傳回數字
count
傳回布爾值
exists()
單表的雙下劃線
字段__條件
__gt 大于
__gte 大于等于
__lt 小于
__lte 小于等于
__in= [] 成員判斷
__range = [3,6] 範圍 3-6
__contains ='' 包含 like
__icontains ='' 忽略大小寫
__startswith ='' 以什麼開頭
__istartswith ='' 以什麼開頭
__endswith ='' 以什麼結尾
__endswith ='' 以什麼結尾
__year ='2019'
__isnull = True 字段值為null