📅  最后修改于: 2023-12-03 15:40:21.766000             🧑  作者: Mango
Django 是一个流行的 Web 应用程序框架,使用其可以快速开发高质量的 Web 应用程序。在使用 Django 进行应用程序开发时,有一些常见的错误需要避免,以确保实现可维护、可扩展和高效的应用程序。
以下是构建 Django 应用程序时应避免的 7 个错误:
查询数据库是 Django 应用程序中常见的任务之一。如果没有正确地使用缓存,重复查询可能会导致应用程序的性能下降。
from django.core.cache import cache
# Bad example
def get_user(id):
return User.objects.get(id=id)
# Good example, uses cache
def get_user(id):
key = f"user_{id}"
user = cache.get(key)
if user is None:
user = User.objects.get(id=id)
cache.set(key, user, timeout=60)
return user
在 Django 模板中执行查询操作会使应用程序性能下降。在 Django 模板中执行查询操作的行为称为“数据库查询暴露”。
<!-- Bad example -->
{% for product in Product.objects.all %}
<div>{{ product.name }}</div>
{% endfor %}
<!-- Good example, pass query result from view -->
<!-- Views.py -->
def product_list(request):
products = Product.objects.all()
return render(request, 'product_list.html', {
'products': products
})
<!-- Product_list.html -->
{% for product in products %}
<div>{{ product.name }}</div>
{% endfor %}
在循环中多次执行查询操作会导致大量查询,并且可能会使应用程序的性能下降。
# Bad example
def get_products(price):
products = []
for category in Category.objects.all():
for product in Product.objects.filter(category=category, price=price):
products.append(product)
return products
# Good example, use prefetch_related
def get_products(price):
categories = Category.objects.prefetch_related('products').all()
return [product for category in categories for product in category.products.filter(price=price)]
Django 提供了模板片段,使得可以将常用的页面部分缓存在缓存中来提高性能。 如果没有正确地使用缓存,可能会导致应用程序的性能下降。
<!-- Bad example -->
{% for product in Product.objects.all %}
<div>{{ product.name }}</div>
{% endfor %}
<!-- Good example, use cache with fragment name -->
{% load cache %}
{% cache 600 "product_list" %}
{% for product in Product.objects.all %}
<div>{{ product.name }}</div>
{% endfor %}
{% endcache %}
当你想使用某个应用程序中的模板时,可以在该应用程序的 templates 目录中使用 {% include %} 模板标记。 这样是错误的,因为在 % include % 中指定的所有相对路径都在包含它的模板的目录中搜索。
# Bad example, include template from wrong directory
{% include 'myapp/templates/mytemplate.html' %}
# Good example, include template from correct directory
{% include 'myapp/mytemplate.html' %}
在视图函数中,必须将上下文对象作为 HttpResponse 对象的参数返回。向 HttpResponse 对象传递的上下文必须是字典对象。
# Bad example
def my_view(request):
context = {'message': 'Hello, World!'}
return render(request, 'my_template.html', context)
# Good example, context is dict
def my_view(request):
context = {'message': 'Hello, World!'}
return render(request, 'my_template.html', context=context)
当你需要执行长时间的或需要大量计算的任务时,你需要使用异步编程。 不要在同步代码上使用大量计算或网络 I/O,而是使用异步编程。
# Bad example, synchronous code
class MyModel(models.Model):
...
@classmethod
def do_long_task(cls):
# This task takes a long time to run
...
# Good example, asynchronous code
class MyModel(models.Model):
...
@classmethod
async def do_long_task(cls):
# This task takes a long time to run
...