4

私は、tastypie を使用して同じタイプの特定のオブジェクトを公開するビューを作成したいと考えていますが、次の2 つの3 つのひねりがあります。

  1. 3 つの個別のクエリを使用してオブジェクトを取得する必要があります。
  2. 基になるモデルに存在しないフィールドを追加する必要があり、そのフィールドの値は、どのクエリから来たかによって異なります。と
  3. データはユーザーごとになります (そのため、リクエストを取得するメソッドの 1 つにフックする必要があります)。

これを達成するために、tastypie ライフサイクルに接続する方法がよくわかりません。「仮想」フィールドを追加するための推奨される方法は、操作対象のバンドルについてのみ認識している脱水メソッドです。

さらに悪いことに、クエリセットを結合する公式の方法はありません。

Tastypie がクエリセット以外のものを受け入れるようにできれば、私の問題は解決するでしょう。その場合、追加のフィールドを追加して、オブジェクトのサブクラスのリストを渡すことができます。

私は他の賢明な解決策を受け入れます。

編集: ツイスト 3 を追加 - ユーザーごとのデータ。

4

4 に答える 4

8

最後のバージョンでは、dehydrate メソッドをオーバーライドする必要があります。

def dehydrate(self, bundle):
    bundle.data['full_name'] = bundle.obj.get_full_name()
    return bundle
于 2011-06-29T08:03:13.220 に答える
7

ここで同様の問題に遭遇しました。私の場合、リスト内の項目はユーザーが「チェック」できました。

  • アイテムが AJAX によって取得されると、そのチェック済みステータスがリソースとともに通常のフィールドとして返されます。
  • アイテムがサーバーに保存されると、リソースの「チェック済み」フィールドがユーザーのセッションに保存されます。

最初はhydrate()anddehydrate()メソッドがこの仕事に最適だと思っていましたがrequest、これらのオブジェクトへのアクセスに問題があることがわかりました。だから私はと行きましalter_data_to_serialize()obj_update()。アイテムは最初に作成されたときにチェックできないので、オーバーライドする必要obj_create()はないと思います。

これがコードですが、まだ適切にテストされていないことに注意してください。

class ItemResource(ModelResource):
    def get_object_checked_status(self, obj, request):
        if hasattr(request, 'session'):
            session = request.session
            session_data = session.get(get_item_session_key(obj), dict())
            return session_data.get('checked', False)
        return False

    def save_object_checked_status(self, obj, data, request):
        if hasattr(request, 'session'):
            session_key = get_item_session_key(obj)
            session_data = request.session.get(session_key, dict())
            session_data['checked'] = data.pop('checked', False)
            request.session[session_key] = session_data

    # Overridden methods
    def alter_detail_data_to_serialize(self, request, bundle):
        # object > resource
        bundle.data['checked'] = \
            self.get_object_checked_status(bundle.obj, request)
        return bundle

    def alter_list_data_to_serialize(self, request, to_be_serialized):
        # objects > resource
        for bundle in to_be_serialized['objects']:
            bundle.data['checked'] = \
                self.get_object_checked_status(bundle.obj, request)
        return to_be_serialized

    def obj_update(self, bundle, request=None, **kwargs):
        # resource > object
        save_object_checked_status(bundle.obj, bundle.data, request)
        return super(ItemResource, self)\
            .obj_update(bundle, request, **kwargs)

def get_item_session_key(obj): return 'item-%s' % obj.id
于 2011-06-25T16:49:35.087 に答える
1

OK、これが私の解決策です。コードは以下です。

注意点:

  1. 作業は基本的にすべて で行いobj_get_listます。そこで、リクエストにアクセスしてクエリを実行します。
  2. からリストを返すことができobj_get_listます。
  3. 他の操作 ( 、など)obj_*に対応する他のすべてのメソッドを使用可能にしたい場合は、それらをオーバーライドする必要があるでしょう。obj_getobj_create
  4. querysetinがないので、tastypie のイントロスペクションにどのフィールドを提供するかを伝えるMetaために を提供する必要があります。object_class
  5. 「仮想」属性 ( で作成obj_get_list) を公開するには、フィールド宣言を追加する必要があります。
  6. フィルターと認証制限は、今は必要ないのでコメントアウトしました。必要に応じて自分で実装する必要があります。

コード:

from tastypie.resources import ModelResource
from tastypie import fields
from models import *
import logging

logger = logging.getLogger(__name__)


class CompanyResource(ModelResource):
    role = fields.CharField(attribute='role')


    class Meta:
        allowed_methods = ['get']
        resource_name = 'companies'
        object_class = CompanyUK
        # should probably have some sort of authentication here quite soon


    #filters does nothing. If it matters, hook them up
    def obj_get_list(self, request=None, **kwargs):
#         filters = {}

#         if hasattr(request, 'GET'):
#             # Grab a mutable copy.
#             filters = request.GET.copy()

#         # Update with the provided kwargs.
#         filters.update(kwargs)
#         applicable_filters = self.build_filters(filters=filters)

        try:
            #base_object_list = self.get_object_list(request).filter(**applicable_filters)
            def add_role(role):
                def add_role_company(link):
                    company = link.company
                    company.role = role
                    return company
                return add_role_company

            director_of = map(add_role('director'), DirectorsIndividual.objects.filter(individual__user=request.user))
            member_of   = map(add_role('member'),   MembersIndividual.objects.filter(individual__user=request.user))
            manager_of  = map(add_role('manager'),  CompanyManager.objects.filter(user=request.user))

            base_object_list = director_of + member_of + manager_of
            return base_object_list #self.apply_authorization_limits(request, base_object_list)
        except ValueError, e:
            raise BadRequest("Invalid resource lookup data provided (mismatched type).")
于 2011-06-12T12:21:24.490 に答える