Django会自动缓存模板吗?
我刚接触Django,正在尝试实现一个在两张图片之间投票的系统。不过,似乎页面出现了缓存的问题,因为每次刷新时,有些数值都不对。我在设置里没有配置任何缓存。
这是我的视图代码:
def rate(request, type):
photos = Photo.objects.order_by('?')[:2]
c = Context({"photos": photos, "type": type})
return render_to_response("base_rate.html", c)
还有模板代码:
{% extends "base.html" %}
{% block body %}
<div class="photo">
<img src="{{photos.0.photo.url}}" alt="Photo" />
<a href="/rate/vote/{{photos.0.id}}/{{photos.1.id}}" class="vote">Vote</a>
<a href="/rate/flag/{{photos.0.id}}" class="flag">Flag</a>
</div>
<div class="photo">
<img src="{{photos.1.photo.url}}" alt="Photo" />
<a href="/rate/vote/{{photos.1.id}}/{{photos.0.id}}" class="vote">Vote</a>
<a href="/rate/flag/{{photos.1.id}}" class="flag">Flag</a>
</div>
{% endblock %}
有些页面显示的对象信息是错误的。这里有一个我遇到的例子:
<div class="photo">
<img src="/img/rate/16photo1.jpg" alt="Photo" />
<a href="/rate/vote/16/17" class="vote">Vote</a>
<a href="/rate/flag/16" class="flag">Flag</a>
</div>
<div class="photo">
<img src="/img/rate/17photo2.jpg" alt="Photo" />
<a href="/rate/vote/16/16" class="vote">Vote</a>
<a href="/rate/flag/16" class="flag">Flag</a>
</div>
第二个投票链接应该是“/rate/vote/17/16”,而标记链接应该是“/rate/flag/17”,但出现了问题,我得到了不一致的数据。
有什么想法吗?
3 个回答
1
order_by('?')
的意思是列表是以 随机 的顺序排列的,所以每次你加载页面时,{{ photos.0 }}
的内容都会不同。
另外:
<a href="/rate/vote/{{photos.1.id}}/{{photos.0.id}}" class="vote">Vote</a>
^^^ ^^^
看起来这可能不太对。
1
Django默认情况下不会缓存这些东西。你要确保你的浏览器、网络服务提供商等没有在缓存这些内容。
看起来你的数据库查询没有返回你期待的结果。你可以通过调试工具直接检查,或者如果需要的话,用打印语句来调试。
话说回来,你真的需要认真考虑一下你的应用设计。用GET请求来对应用进行状态改变是个非常糟糕的主意,尤其是你现在的做法。你需要把那些链接改成POST请求,使用一个统一的表单。否则,你会发现一些随机的网络爬虫会破坏你的应用。
8
看看我代码中的这个部分,我在模板里写了这些:
{{ mytable.0.pk }}
{{ mytable.1.pk }}
{{ mytable.0.pk }}
{{ mytable.3.pk }}
然后我得到了这个输出:
91596
54774
156800
23593
这有点奇怪,直到你考虑到 Django 在执行数据库查询时是非常懒惰的。这是我在 MySQL 日志中看到的一次页面加载的记录:
SELECT `mytable`.`id` FROM `mytable` ORDER BY RAND() LIMIT 1
SELECT `mytable`.`id` FROM `mytable` ORDER BY RAND() LIMIT 1 OFFSET 1
SELECT `mytable`.`id` FROM `mytable` ORDER BY RAND() LIMIT 1
SELECT `mytable`.`id` FROM `mytable` ORDER BY RAND() LIMIT 1 OFFSET 3
每次你使用点符号的时候,它都会执行一个全新的查询。我建议你把代码改成这样:
def rate(request, type):
photos = list(Photo.objects.order_by('?')[:2])
c = Context({"photos": photos, "type": type})
return render_to_response("base_rate.html", c)
因为 list()
强制进行了评估,所以它会立即执行查询。此外,这两个项目的数据已经被缓存了,所以没有必要再去数据库查询一次。这样就没问题了。