首页 > 解决方案 > Django中的速度优化

问题描述

我正在构建一个博客应用程序,并且我也在考虑在其中实现视频帖子。我正在尝试优化 Web App 在开发和生产中的速度。

过去几个月,我在PythonAnywhere上部署了许多用 Django 构建的站点。我注意到大多数网站都包含简单的功能,例如:Create- 、、、、、博客等。但是即使只有 2 到 5 页,它们也很慢。EditImage UploadListViewDetailView500 to 600 lines of Code (python)

谈发展:-

当我打开一个包含 100 到 150 个带图片的博客的页面时,打开页面需要 2 到 3 秒,然后我认为这可能是因为有更多的博客和查询,然后我使用Django检查了页面的查询和查询的时间-Debug-Toolbar然后我删除了除 1 个帖子之外的所有帖子,之后我看到了debug-toolbar,它显示

我删除了一些查询,但结果仍然相同。

我也搜索了它,然后我找到了一篇使用select_related优化查询的帖子,然后我也使用了它,但我没有看到任何太大的改进。

for loops我曾经作为初学者越来越多,Template但后来我在某处读到(抱歉,我不记得出处)“使用逻辑功能,如for loop,if elseviews 代替templates

谈论生产:-

在我的生产站点中-登录,创建或上传文件,在站点中加载图像在站点中似乎很慢。所以我认为这可能是因为我使用的数据库,所以我联系他们询问数据库是否会降低站点速度(性能)然后他们说:-

您网站的速度在很大程度上取决于您为处理传入请求而编写的代码的速度。特定的数据库可能不会影响图像下载的速度,但事实上您正在不使用静态文件系统会。

但我只是像任何人一样编写代码来显示博客文章列表,我正在使用MEDIA ROOTSTATIC files之后图像仍然加载缓慢。

而且我还根据Django-Documentation-About-Performance and Optimization工作,例如 :- using counting objects using .count() will increase the speed

在那之后,我仍然没有找到任何完美的解决方案来优化ProductionDevelopment.

我正在处理并尝试优化网站的博客 Web 应用程序的视图和模型

模型.py

class BlogPost(models.Model):
    user = models.ForeignKey(User,default='',null=True,on_delete = models.CASCADE)
    title = models.CharField(max_length=500,default='',validators=[validate_is_profane])
    description = models.TextField()
    date = models.DateTimeField(null=True,default=timezone.now)
    image = models.ImageField(upload_to='blog_posts',blank=True,null=True)
    slug = models.SlugField(null=True)

视图.py

def posts(request):
    blog_profile = get_object_or_404(Profile, user_id=request.user)
    now = timezone.now()
    posts = Post.objects.filter(date__lte=now).order_by('-date').exclude(user=request.user)

    if request.method == 'POST':
        new_blog_post = BlogPostForm(request.POST,
                                    request.FILES,
                                    instance=request.user.profile)

        if which_post_form.is_valid():
            new_blog_post = new_blog_post.save(commit=False)
            new_blog_post.save()
            return redirect('home')

    else:
        new_blog_post = BlogPostForm(instance=request.user.profile)

    context = {
        'posts':posts,
        'blog_profile':blog_profile,
        'new_blog_post':new_blog_form,
    }

    return render(request, 'post_list.html', context)

post_list.html

{% for topic in posts %}

<br>


<a href="{% url 'user_profile' user.id %}">{{ topic.user }}</a>

<p>{{ topic.title|truncatechars:10 }}</p>

{% if topic.image %}
<br>
<a><img src="{{ topic.image.url }}" id="myImg" width="300"></a>
<br>
{% endif %}


<div id="myModal" class="modal">
    <span class="close">&times;</span>
    <img class="modal-content" id="img01">
    <div id="caption"></div>
</div>



<a>{{ topic.description|slice:":10" }}</a>

<a href="{{ topic.get_absolute_url }}">More</a>

{% endblock content %}

如果您有任何进一步的解决方案,您如何优化您的网站。那么我将非常感谢您的答案和建议。

标签: pythondjangooptimizationquery-optimization

解决方案


如果您有大量数据,我发现有两件事可能会导致性能下降,其中第一件事更有可能是一个问题:

默认情况下,模板中的访问topic.user将对每个项目进行额外查询posts,因为该属性访问需要User从不同的表中加载模型的信息。select_related('user')在获取查询集时执行 aPost会将用户信息加载到与帖子相同的查询中:

Post.objects.filter(date__lte=now) \
    .order_by('-date') \
    .exclude(user=request.user) \
    .select_related('user')

我强烈怀疑以这种方式避免每个帖子的查询将解决您的性能问题,因为如果一个典型的查询需要大约 10 毫秒并且您需要进行数百个查询,那么很容易将您的响应时间延长到几秒钟。由于您实际上并没有读取大量数据,因此查询所花费的时间将由固定开销支配,您可以通过简单地执行较少的查询来避免这些开销。


虽然除非您有大量帖子(数万或更多),否则不太可能成为问题,但排序您Post的 sdate将需要数据库读取表的每一行并在返回任何行之前对其进行排序。对于几百个对象,这成本可以忽略不计,但对于数千个对象,它会更慢。

如果您在查询和排序的字段上添加索引,则可以帮助数据库有效地执行操作:

class Post(models.Model):
    ...
    class Meta:
        indexes = [
            models.Index(fields=['-date'], name='date_ordering'),
        ]

推荐阅读