ORM詳細操做

 
 
 
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數據的時候,它幫你作校驗,若是校驗不經過就拒絕此次請求
相關文章
相關標籤/搜索