【发布时间】:2015-05-23 01:54:24
【问题描述】:
TLDR:自定义视图/模板仅有时会调用自定义模型方法。有时是错误的结果(没有来自方法的打印消息),有时是正确的结果(有来自方法的打印消息)。
我是 Mezzanine 的新手(更习惯于 Pyramid),并且在某些模板渲染方面遇到了一个奇怪的非确定性问题。我创建了一个带有内部 Django 应用程序的夹层项目,用于添加 3 种新类型:实验(Page、RichText)、Instrument(Page、RichText)、DailyStatus(Displayable、Ownable、RichText)。我在 DailyStatus 上定义了一个 ForeignKey 以将其链接到单个实验。
由于 DailyStatus 不是 Page 的子类,因此我创建了自己的视图和模板(扩展 base.html)。该模板从博客详细信息模板中汲取了很多内容,因为 DailyStatus 具有类似的目的。在模板中,我调用了两种方法来获取使用 DailyStatus status_date DateField 的 Experiment(get_previous_by_status_date 和 get_next_by_status_date)中的上一个和下一个 DailyStatus。
有时,当我访问每日状态页面时,上一个/下一个按钮会按预期工作(显示实验中的下一个状态,或者在实验中显示第一个/最后一个状态)。但其他时候,当服务器重新启动/重新加载时,它似乎是通过 publish_date 选择 prev/next 或者只是不工作。它永远不会在服务器的单个实例期间切换这些状态。我已经使用 pdb 和 ipdb 尝试对此进行调试,并且已经到了调用daily_status_inst.get_previous_by_status_date() 产生错误结果而daily_status_inst._get_next_or_previous_by_status_date(False) 产生正确结果的地步。正确状态和错误状态之间的上下文似乎没有任何不同(我将字典转储到文件中)。我已将 print 添加到各个 prev/next 方法中,有时它们甚至似乎都没有被调用(没有输出),但它们返回的值不正确。
有人知道发生了什么吗?或任何其他有用的调试技巧?我的 DailyStatus 模型如下:
class DailyStatus(Displayable, Ownable, RichText):
experiment = models.ForeignKey(Experiment, related_name="daily_statuses")
status_date = models.DateField(_("Status Date"))
class Meta:
verbose_name = _("Daily Status")
verbose_name_plural = _("Daily Statuses")
ordering = ("-status_date",)
order_with_respect_to = "experiment"
def __str__(self):
return self.title
def get_absolute_url(self):
from django.core.urlresolvers import reverse
return reverse('daily_status_detail',
kwargs={
"experiment": self.experiment.slug,
"slug": self.slug,
})
def _get_next_or_previous_by_status_date(self, is_next, **kwargs):
arg = "status_date__gt" if is_next else "status_date__lt"
order = "status_date" if is_next else "-status_date"
lookup = {arg: self.status_date, "experiment": self.experiment}
try:
queryset = DailyStatus.objects.published
except AttributeError:
queryset = DailyStatus.objects.all
try:
dstatus = queryset(**kwargs).filter(**lookup).order_by(order)[0]
return dstatus
except IndexError:
return False
def get_next_by_status_date(self, **kwargs):
dstatus = self._get_next_or_previous_by_status_date(True, **kwargs)
return dstatus
def get_previous_by_status_date(self, **kwargs):
dstatus = self._get_next_or_previous_by_status_date(False, **kwargs)
return dstatus
最简单的模板:
<html>
<head>
</head>
<body>
{{ daily_status.get_previous_by_status_date }}
<p></p>
{{ daily_status.get_next_by_status_date }}
</body>
</html>
使用:
* Mezzanine 3.1.10
* Django 1.6.11
* Python 3.4.3
* SQLite 3.8.10.1
* Darwin 14.3.0
感谢您的帮助。
更新 1:
我已经追踪到 prev/next 方法是否为_curried。当他们被咖喱时,它永远不会调用实际的方法(或者至少不打印任何输出)。当它是正常绑定方法时,我得到预期的输出:
# custom view
status_posts = DailyStatus.objects.published().filter(experiment__slug=experiment).all()
print(status_posts.get_next_by_status_date)
# get_object_or_404 and so on with rendering...
# print produces:
<bound method DailyStatus._curried of <DailyStatus: 2013: Update 1>>
# or (after a couple server restarts):
<bound method DailyStatus.get_next_by_status_date of <DailyStatus: 2013: Update 1>>
【问题讨论】:
标签: python django python-3.x mezzanine