1. ORM經常使用字段和屬性
1.
AutoField(primary_key=True)
2.
CharField(max_length=32)
3.
IntgerField()
4.
DateField()
5.
DateTimeField()
1.
auto_now_add --> 建立的時候自動填充當前時間
2.
auto_now --> 每次修改的時候自動把當前時間更新
2. 關係字段
1. ForeignKey(to="類名",
related_name=「xx」) --> 1對多 ,
外鍵一般設置在多的那一邊,related_name是反向查詢使用
2. ManyToMany(to="類名",related_name="xx") --> 多對多,
一般設置在正向查詢多的那一邊
3. ORM通常操做
1. 必知必會13條
1. 返回QuerySet對象的
1. all()
2. filter()
3. values()
4. values_list()
5. exclude()
6. order_by()
7. reverse()
8. distinct()
2. 返回具體對象的
1. get()
2. first()
3. last()
3. 返回布爾值的
1. exists()
4. 返回具體數值的
1. count()
2. 單表查詢的雙下劃線
1. models.Book.objects.filter(id__
gt=1) #查詢id大於1的book對象
2. models.Book.objects.filter(id__in=[1,2,3]) #查詢id在1,2,3中的的全部對象
3. models.Book.objects.filter(id__range=[1,5]) #查詢id在1到5的範圍的對象
4. models.Book.objects.filter(title__contains="沙河") #查詢書名中包含沙河的全部對象
5. models.Book.objects.filter(title__icontains="沙河") #查詢書名中包含沙河的全部對象,忽略大小寫
6. models.Book.objects.filter(title__startswith="沙河") #查詢書名是以沙河開頭的全部對象
7. models.Book.objects.filter(title__endswith="沙河") #查詢書名是以沙河結尾的全部對象
8. models.Book.objects.filter(publish_date__year=2017) #查詢出版社出版年份是2017年的全部書的對象
9. models.Book.objects.filter(publish_date__month=2) #查詢出版社月份是2月的全部書的對象
3. 外鍵的跨表查詢
a.正向查找
1. 基於對象
book_obj = models.Book.object.get(id=1)
book_obj.publisher.name
2. 基於雙下劃線的
models.Book.objects.filter(id=1).values("publisher__name")
# 先獲取id爲1的書的對象,而後到publisher的出版社對象中找name屬性,values中必定要加引號和雙下劃線
如:
ret = models.Book.objects.filter(id=1).values('publisher__name')
print(ret)
<QuerySet [{'publisher__name': '清華大學出版社'}]>
b.反向查找(由出版社查書)
1. 基於對象
publisher_obj = models.Publisher.objects.get(id=1)
默認反向查找的時候是
表名加_set
publisher_obj.book_set.all()
若是在外鍵中設置了
related_name="books"
publisher_obj.books.all()
2. 基於雙下劃線
models.Publisher.objects.filter(id=1).values(
"book__title") #這裏也是用的book
若是配置了related_query_name="books"
models.Publisher.objects.filter(id=1).values("books__title")
這裏有個很大的疑惑,爲何反向查找時,表名Book不能夠,要用小寫的book呢,這個沒有定義的:
class publisher(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(null=False, max_length=20)
class
Book
(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=64, null=False, unique=True)
price = models.DecimalField(max_digits=5, decimal_places=2, default=99.99)
publisher = models.ForeignKey(to='publisher')
publisher_obj = models.publisher.objects.get(id=9)
ret = publisher_obj.
book_set
.all() #若是用了Book會報錯,沒有這個屬性
print(ret)
返回的對象??
<QuerySet [<Book: Book object>, <Book: Book object>]>
4. 分組和聚合
1. 聚合
from django.db.models import Avg, Sum, Max, Min, Count
models.Book.objects.all().
aggregate(Avg("price"))
2. 分組
book_list = models.Book.objects.all().annotate(author_num=Count("author")) #先拿出全部的Book對象,而後按id分組,接着拿id去統計做者數量
#分組詳解
ret = models.Book.objects.all().annotate(author_num=Count('authors')) #這裏的authors是寫了related_query_name='authors'
for i in ret:
print(i.author_num)
#返回的對象和sql語句
(0.000) SELECT @@SQL_AUTO_IS_NULL; args=None
(0.069) SELECT `app_publisher_book`.`id`, `app_publisher_book`.`title`, `app_publisher_book`.`price`, `app_publisher_book`.`publisher_id`, `app_publisher_book`.`author_id`, COUNT(`app_publisher_author_book`.`author_id`) AS `author_num` FROM `app_publisher_book` LEFT OUTER JOIN `app_publisher_author_book` ON (`app_publisher_book`.`id` = `app_publisher_author_book`.`book_id`) GROUP BY `app_publisher_book`.`id` ORDER BY NULL; args=()
3
3
3
1
[Finished in 1.7s]
5. F和Q
1. 當須要字段和字段做
比較的時候用F查詢
2. 當查詢條件是
或 的時候 用Q查詢,由於
默認的filter參數都是且的關係
6. 事務
保證數據的原子性操做!!!
import os
if __name__ == '__main__':
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings")
import django
django.setup()
import datetime
from app01 import models
try:
from django.db import transaction #導入事務模塊
with transaction.atomic(): #使用with關鍵字,若是下面的內容出錯,程序會自動回滾,把執行過的sql語句回滾到最原始的狀態
new_publisher = models.Publisher.objects.create(name="火星出版社")
models.Book.objects.create(title="橘子物語", publish_date=datetime.date.today(), publisher_id=10) # 指定一個不存在的出版社id
except Exception as e:
print(str(e))
7. 執行原生的SQL語句(瞭解便可)
CSRF跨站請求僞造
1. 釣魚網站的頁面和正經網站的頁面對瀏覽器來講有什麼區別? (頁面是怎麼來的?)
釣魚網站的頁面是由 釣魚網站的服務端給你返回的
正經網站的網頁是由 正經網站的服務端給你返回的
2. Django中內置了一個專門處理csrf問題的中間件
django.middleware.csrf.CsrfViewMiddleware
這個中間件作的事情:
1. 在render返回頁面的時候,在頁面中塞了一個隱藏的input標籤
用法:
咱們在頁面上
form表單 裏面 寫上 {% csrf_token %}
<input type="hidden" name="csrfmiddlewaretoken" value="8gthvLKulM7pqulNl2q3u46v1oEbKG7BSwg6qsHBv4zf0zj0UcbQmpbAdijqyhfE">
2. 當你提交POST數據的時候,它幫你作校驗,若是校驗不經過就拒絕此次請求