我有一个简单的模型 MyModel ,其日期字段名为 publication_date 。我还有一个自定义管理器,可根据此日期字段过滤我的模型。
此自定义管理器可通过 .published 访问,默认可通过 .objects 访问。
from datetime import date, datetime
from django.db import models
class MyModelManager(models.Manager):
def get_query_set(self):
q = super(MyModelManager, self).get_query_set()
return q.filter(publication_date__lte=datetime.now())
class MyModel(models.Model):
...
publication_date = models.DateField(default=date.today())
objects = models.Manager()
published = MyModelManager()
这样,我可以访问管理员中的所有对象,但只能访问我的视图中的已发布对象(使用 MyModel.published.all()查询集)。
我也有
def get_previous(self):
return self.get_previous_by_publication_date()
def get_next(self):
return self.get_next_by_publication_date()
我在模板中使用的:查看对象时,我可以使用
链接到上一个和下一个对象{{ object.get_previous }}
问题是:这会返回默认查询集中的上一个对象(对象),而不是我的自定义对象(已发布)。
我想知道如何告诉这个基本模型函数(get_previous_by_FOO)来使用我的自定义管理器。 或者,如果不可能,如何用另一种解决方案做同样的事情。
提前感谢任何建议。
修改
在我的urlconf中使用通用视图中的object_detail以这种方式调用视图。
(r'^(?P<slug>[\w-]+)$', object_detail,
{
'queryset': MyModel.published.all(),
'slug_field': 'slug',
},
'mymodel-detail'
),
我正在使用Django 1.2。
答案 0 :(得分:1)
实际上,get_next_or_previous_by_FIELD()Django函数(由get_previous_by_publication_date ...使用)使用default_manager。
所以我已经调整它以重新实现我自己的效用函数
def _own_get_next_or_previous_by_FIELD(self, field, is_next):
if not self.pk:
raise ValueError("get_next/get_previous cannot be used on unsaved objects.")
op = is_next and 'gt' or 'lt'
order = not is_next and '-' or ''
param = smart_str(getattr(self, field.attname))
q = Q(**{'%s__%s' % (field.name, op): param})
q = q|Q(**{field.name: param, 'pk__%s' % op: self.pk})
qs = MyModel.published.filter(q).order_by('%s%s' % (order, field.name), '%spk' % order)
try:
return qs[0]
except IndexError:
def get_previous(self):
return self._own_get_next_or_previous_by_FIELD(MyModel._meta.fields[4], False)
def get_next(self):
return self._own_get_next_or_previous_by_FIELD(MyModel._meta.fields[4], True)
这不是一个非常干净的解决方案,因为我需要对查询集和使用的字段进行硬编码,但至少它是有效的。