2

我有一个带有自定义管理器的模型,目的是过滤“活动”对象,即具有start_date低于当前时间和end_date大于当前时间的对象。

这是我的相关部分models.py

from django.utils.timezone import now

class ActiveObjectManager(models.Manager):
    def get_query_set(self):
        return super(ActiveObjectManager, self).get_query_set().\
            filter(start_date__lt=now(), end_date__gt=now())

class Object(models.Model):
    start_date = models.DateTimeField(_('Service start date'), \
        auto_now_add=False, null=False, blank=False)
    end_date = models.DateTimeField(_('Service end date'), auto_now_add=False, \
        null=False, blank=False)
    ...
    objects = models.Manager()
    objects_active = ActiveObjectManager()

这个管理器在整个应用程序和 Django shell 中都能很好地工作。但是,如果我在管理界面中创建一个对象,并将其设置start_date为“现在”选择器,那么美味派提供的 API 不会显示这个新创建的对象(尽管它确实显示了较旧的对象)。管理员列表正确地将新对象显示为活动的。

这是我的相关部分api.py

from app.models import Object

class ActiveObjectResource(ModelResource):
    modified = fields.BooleanField(readonly=True)

    class Meta:
        resource_name = 'activeobjects'
        queryset = Object.objects_active.all()

我强烈怀疑,由于类ActiveObjectResource被解释一次,这两个now()调用只执行一次,即 API 子系统总是filter()使用相同的值start_date__ltend_date__gt参数调用(now()在我运行后立即返回的值manage.py runserver) .

即使我像这样在资源类中进行过滤,这个问题仍然存在:

class ActiveObjectResource(ModelResource):
    ...
    class Meta:
        queryset = Object.objects.\
            filter(start_date__lt=now(), end_date__gt=now())

此外,如果我通过这样的可调用对象,问题仍然存在:

class ActiveObjectResource(ModelResource):
    ...
    class Meta:
        queryset = Object.objects.filter(start_date__lt=now, end_date__gt=now)

有没有办法可以重写ActiveObjectManagerActiveObjectResource克服这个问题?

更新: 好的,看来我需要重写get_object_list以实现对 queryset 的每个请求的更改,例如:

class ActiveObjectResource(ModelResource):
    class Meta:
        queryset = Object.objects.all()

    def get_object_list(self, request):
        return super(MyResource, self).get_object_list(request).\
            filter(start_date__lt=now, end_date__gt=now)

但是当我已经有一个模型级别的自定义管理器为我完成这项工作时,我讨厌重复这个逻辑。

所以我的问题是:如何在我的内部使用我的自定义模型管理器ModelResource

4

1 回答 1

3

好吧,关于ModelResource.Meta. 这是来自美味派文档的摘录

如果您在其中放置任何可调用对象,它们只会被评估一次(当 Meta 类被实例化时)。这尤其会影响与日期/时间相关的事物。请参阅 :ref:cookbook 以了解解决此问题的方法。

这样:

一种常见的模式是需要通过更改每个请求的内容来限制查询集,例如 date/time。您可以通过轻轻修改 get_object_list 来完成此操作

所以,是的,似乎实现你想要做的事情的唯一方法就是声明get_object_list.

新更新:因为get_object_list只是一个return self._meta.queryset._clone(),尝试这样的事情:

class ActiveObjectResource(ModelResource):
    class Meta:
        queryset = Object.objects_active.all()

    def get_object_list(self, request):
        return Object.objects_active.all()
于 2012-07-20T07:38:09.567 回答