You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免Django高频访问视图中的重复数据库查询?

嘿,针对你遇到的Django视图重复执行查询的问题,这里有几个实用的解决方案,结合你给出的代码场景来拆解:

1. 利用Django内置缓存框架(最适合你的场景)

你的related_negos和all_jobs更新频率很低(一个每2个月、一个每周),完全适合用缓存把查询结果存起来,避免每次请求都跑数据库。Django的低级别缓存API可以精准控制要缓存的内容:

from django.core.cache import cache

@access_to(['is_admin','is_job_seeker'])
def negotiationView(request,slug,id,code):
    obj = get_object_or_404(Group,slug=slug)
    nego = get_object_or_404(Negotiation,id=id,code=code)
    
    # 缓存related_negos,按tag ID生成唯一缓存键,有效期60天
    cache_key_related = f"related_negos_{nego.tag.id}"
    related_negos = cache.get(cache_key_related)
    if not related_negos:
        # 查询后转成列表(QuerySet不能直接序列化缓存)
        related_negos = list(Negotiation.objects.filter(tag=nego.tag))
        cache.set(cache_key_related, related_negos, timeout=60*60*24*60)
    
    # 缓存all_jobs,按Group ID生成唯一缓存键,有效期7天
    cache_key_jobs = f"group_published_jobs_{obj.id}"
    all_jobs = cache.get(cache_key_jobs)
    if not all_jobs:
        all_jobs = list(obj.job_offers.filter(published=True))
        cache.set(cache_key_jobs, all_jobs, timeout=60*60*24*7)
    
    # 后续业务逻辑...

注意:当你创建新tag或发布新job时,记得手动清除对应缓存(比如调用cache.delete(cache_key_related)),这样用户就能看到最新数据了。

2. 单次请求内避免重复查询(辅助优化)

如果你的视图里多次用到同一个查询结果,还可以把它存在request对象里,避免同一次请求内重复执行:

# 比如视图里多次需要related_negos的话
if not hasattr(request, '_cached_related_negos'):
    request._cached_related_negos = list(Negotiation.objects.filter(tag=nego.tag))
related_negos = request._cached_related_negos

这个方法只解决单次请求内的重复,跨请求还是得靠缓存框架。

3. 模板层面缓存渲染片段

如果这些查询结果是直接在模板里渲染的,还可以用Django的模板缓存标签,直接缓存渲染后的HTML片段,既省查询又省渲染时间:

{% load cache %}

{# 缓存related_negos的渲染结果,有效期60天 #}
{% cache 5184000 related_negos_block nego.tag.id %}
    {% for nego_item in related_negos %}
        <div>{{ nego_item.title }}</div>
    {% endfor %}
{% endcache %}

{# 缓存all_jobs的渲染结果,有效期7天 #}
{% cache 604800 group_jobs_block obj.id %}
    {% for job in all_jobs %}
        <div>{{ job.title }}</div>
    {% endfor %}
{% endcache %}
4. 数据库索引优化

即使最终还是要执行查询,给查询字段加索引也能大幅提升速度。比如在你的模型里给常用过滤字段加索引:

class Negotiation(models.Model):
    tag = models.ForeignKey(Tag, on_delete=models.CASCADE, db_index=True)
    # 其他字段...

class JobOffer(models.Model):
    published = models.BooleanField(default=False, db_index=True)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    # 其他字段...

这样数据库会更快找到符合条件的数据,减少查询耗时。


内容的提问来源于stack exchange,提问作者user9865749

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:01:37