3

Django + TastyPie + Backbone.jsを使用しています。ここで推奨されているように、最初のページの読み込み後にモデルをフェッチするのではなく、最初のリクエストでモデルの初期データをブートストラップする方法を見つけようとしています: http://backbonejs.org/#FAQ-bootstrap

2 つの問題があります。1 つは単一の Django モデルをロードしようとするもので、もう 1 つはクエリセットをシリアル化しようとするものです。

user例として、Django ユーザーであり、ログインしている現在のユーザーを表すコンテキストで呼び出される変数があります。

私はこれをしたくありません:

var curUser = new App.Models.User({id: 1});
curUser.fetch();

ユーザーモデルが既にロードされているため、サーバーに別のリクエストを発生させます。

このデータを次のようなバックボーン モデルにブーストラップしたいと考えています。

var curUser = new App.Models.User({{user|json}});

( Django でバックボーンのブートストラップ モデルをロードする方法に似ていますが、すべてを json に変換する各ビューで特別なケースを実行したくありません)

json に変換するカスタム テンプレート フィルターを作成した場所

def json(object):
    """Return json string for object or queryset.    
    """
    if isinstance(object, QuerySet):
        return mark_safe(serialize('json', object))
    if isinstance(object, Model):
        object = object.to_dict()
    return mark_safe(simplejson.dumps(object))

register.filter('json', json)

問題は、django モデルをシリアル化すると、次のような結果が得られることです。

[{"pk": 1, "model": "auth.user", "fields": {"username": "user@gmail.com", "first_name": "Jeremy", "last_name": "Keeshin", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2013-07-15T22:31:02", "groups": [], "user_permissions": [], "password": "passwordhash", "email": "user@gmail.com", "date_joined": "2012-06-14T00:59:18"}}]'

私が本当に欲しいのは、TastyPie を使用して定義した API と一致する json 表現です。

class UserResource(ModelResource):

    """A resource for the User model."""

    class Meta:
        queryset = User.objects.all()
        resource_name = 'user'
        authorization = Authorization()
        fields = ['username', 'first_name', 'last_name', 'id']
        filtering = {
            'username': ALL,
            'email': ALL,
            'first_name': ALL,
            'last_name': ALL
        }

ここでは、モデルをシリアル化するときにすべてではなく、いくつかのフィールドのみが返されます。Django では特定のフィールドのみをシリアル化できることは知っていますが、これらのフィールドはモデルごとに設定されているため、すべてのビューにその呼び出しを含めたくありません。

ここで同様の回答が表示されますDjango Serialize Queryset to JSON to construct RESTful response with only field information and idですが、これにはすべてのビューでこの呼び出しを記述する必要があります。

私の現在の解決策はto_dict、ユーザーモデルにモンキーパッチを適用したメソッドを追加することです

def to_dict(self):
    """Return a subset of fields as a dictionary."""
    return {
        'id': self.id,
        'first_name': self.first_name,
        'last_name': self.last_name,
        'email': self.email
    }

これはシリアライズしやすいからです。さらに、django モデルは (1 つのリストではなく) 単独でシリアル化することはできません。シリアル化できるのはクエリセットのみです。

多くの人が、最初のページ読み込み時に (特に TastyPie を使用する場合に) django モデル データをバックボーン モデルにブートストラップするための良い方法を考え出していると思いますが、これを行うための合理的な方法を見つけられませんでした。

クエリセットを使用すると、さらに多くの django 情報が渡されます。シリアライゼーションを TastyPie API からの出力と一致させる方法を見つけようとしています。

django モデルとクエリセットをバックボーン モデルにブーストするためのベスト プラクティスはありますか?

アップデート:

次のようなTastyPieバンドルを使用するようにjsonフィルターを変更しました

from core.api import UserResource
from core.api import UserProfileResource
from tastypie.serializers import Serializer


def json(object):
    """Return json string for object or queryset."""

    TYPE_TO_RESOURCE = {
        'User': UserResource,
        'UserProfile': UserProfileResource
    }

    Resource = TYPE_TO_RESOURCE[object.__class__.__name__]

    r = Resource()
    bundle = r.build_bundle(object)
    r.full_dehydrate(bundle)
    s = Serializer()
    return mark_safe(s.serialize(bundle, 'application/json'))

ソース: http://django-tastypie.readthedocs.org/en/latest/cookbook.html#using-your-resource-in-regular-views

これはより近いようで、単一のモデルで作業し、TastyPie にリストしたいフィールドを DRY のままにしますが、まだ複数のモデルを処理していません。これをフィルターに入れることが問題になるかどうかもわかりません。

アップデート

これも使用してください:https://gist.github.com/1568294/4d4007edfd98ef2536db3e02c1552fd59f059ad8

def json(object):
    """Return json string for object or queryset."""

    TYPE_TO_RESOURCE = {
        'User': UserResource,
        'UserProfile': UserProfileResource,
    }

    if isinstance(object, QuerySet):
        Resource = TYPE_TO_RESOURCE[object[0].__class__.__name__]
        r = Resource()

        bundles = [r.build_bundle(model) for model in object]
        bundle = [r.full_dehydrate(b) for b in bundles]

    elif isinstance(object, Model):
        Resource = TYPE_TO_RESOURCE[object.__class__.__name__]
        r = Resource()
        bundle = r.build_bundle(object)
        r.full_dehydrate(bundle)
    else:
        mark_safe(simplejson.dumps(object))

    s = Serializer()
    return mark_safe(s.serialize(bundle, 'application/json'))
4

0 に答える 0