Django小技巧16: 數據庫訪問優化

Django小技巧16: 數據庫訪問優化

Posted November 05, 2018

#錯綜複雜

翻譯整理自: simpleisbetterthancomplex.com

本篇分享數據庫訪問優化相關, 讀完這些並不是讓你立即去優化代碼, 更多的時候對於現有代碼的優化, 需要藉助Django Debug Toolbar來分析後, 再去相應的優化代碼, 但今天要說的是一些簡單的技巧, 用於你在編寫代碼的時候就所有規避不好用法, 使用推薦的用法.

訪問外鍵值

如果你只需外鍵的ID

Python

Do

post.author_id

Python

Don't

post.author.id

如果你的博文中有一個 author 的外鍵,Django 會自動將主鍵存儲在屬性author_id中, 而在author屬性則是一個惰性的數據庫引用。如果你如果使用author來訪問 ID, 數據則會多出一個額外的查詢,就會產生開銷。

批量插入Many to Many字段

Python

Do

user.groups.add(administrators, managers)

Python

Don't

user.groups.add(administrators)
user.groups.add(managers)

Count QuerySets

如果你只需獲取 QuerySet count

Python

Do

users = User.objects.all()
users.count()

# Or in template...
{{ users.count }}

Python

Don't

users = User.objects.all()
len(users)

# Or in template...
{{ users|length }}

Empty QuerySets

如果你只想知道 QuerySets 是否爲空.

Python

Do

groups = Group.objects.all()
if groups.exists():
    # Do something...

Python

Don't

groups = Group.objects.all()
if groups:
    # Do something...

減少不必要的查詢次數

就是之前講過的 select_related

Python

Do

review = Review.objects.select_related('author').first()  # Select the Review and the Author in a single query
name = review.author.first_name

Python

Don't

review = Review.objects.first()  # Select the Review
name = review.author.first_name  # Additional query to select the Author

只檢索需要的字段

假設模型Invoice有50個字段,你想要創建一個表格只顯示摘要信息,包含numberdatevalue.

Python

Do

# views.py
# If you don't need the model instance, go for:
invoices = Invoice.objects.values('number', 'date', 'value')  # Returns a dict

# If you still need to access some instance methods, go for:
invoices = Invoice.objects.only('number', 'date', 'value')  # Returns a queryset

# invoices.html
<table>
  {% for invoice in invoices %}
    <tr>
      <td>{{ invoice.number }}</td>
      <td>{{ invoice.date }}</td>
      <td>{{ invoice.value }}</td>
    </tr>
  {% endfor %}
</table>

Python

Don't

# views.py
invoices = Invoice.objects.all()

# invoices.html
<table>
  {% for invoice in invoices %}
    <tr>
      <td>{{ invoice.number }}</td>
      <td>{{ invoice.date }}</td>
      <td>{{ invoice.value }}</td>
    </tr>
  {% endfor %}
</table>

批量更新

使用 F() 批量更新.

Python

Do

from django.db.models import F

Product.objects.update(price=F('price') * 1.2)

Python

Don't

products = Product.objects.all()
for product in products:
    product.price *= 1.2
    product.save()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章