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シェルでうまく機能します。ただし、管理インターフェースでオブジェクトを作成し、start_dateを「now」セレクターに設定すると、tastypieによって提供される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が1回解釈されているため、2つのnow()呼び出しが1回だけ実行されていることです。つまり、APIサブシステムは常にfilter()同じ値start_date__ltとパラメーター(実行直後にend_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)

これを書き直しActiveObjectManagerたりActiveObjectResource、克服したりする方法はありますか?

更新: OK、クエリセットに対するリクエストごとの変更をget_object_list実現する には、オーバーライドする必要があるようです。たとえば、次のようになります。

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

さて、 の queryset についてModelResource.Meta。以下は、tastypie のドキュメントからの抜粋です。

これに callable を配置すると、一度だけ評価されます (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 に答える