2017-12-11 14 views
0

私はthisGoogle cacheDjango MPTTファミリをシリアル化して階層化するには?

のための解決策を見つけることを試みていたと私はこのような解決策を考え出した可能性:

import json 

from mptt.utils import tree_item_iterator 
from rest_framework import generics 
from rest_framework.response import Response 

from .models import Category 

def tree_family_items_to_json(instances): 
    data = '' 
    channel = '"{}"'.format(instances[0].channel.slug) 
    for category, structure in tree_item_iterator(instances): 
     if structure['new_level']: 
     data += '{' 
     else: 
      data += '],' 
      data += '"channel": {}'.format(channel) 
      data += '},{' 
     data += '"slug": "{}",'.format(category.slug) 
     data += '"name": "{}",'.format(category.name) 
     data += '"subcategories": [' 
     for level in structure['closed_levels']: 
      data += '],' 
      data += '"channel": {}'.format(channel) 
      data += '}' 

    return json.loads(data) 

class CategoryFamily(generics.RetrieveAPIView): 
    lookup_field = 'slug' 
    queryset = Category.objects.all() 

    def retrieve(self, request, *args, **kwargs): 
     instances = self.get_object().get_family() 
     json_data = tree_family_items_to_json(instances) 
     return Response(json_data) 

ポイントである私はMPTTからtree_item_iteratorを使用したこと今、私はもっと派手なものを探しています。

これはしばらくの間必要でした。しかし、今はどれくらいの期間は確実でしょうか。

ここで

答えて

0

は残りAPIのツリー構造を持つために一つの方法です。私の場合は

# serializers.py 
class CategoryTreeSerializer(ModelSerializer): 
    children = SerializerMethodField(source='get_children') 
    class Meta: 
     fields = ('children',) # add here rest of the fields from model 

    def get_children(self, obj): 
     children = self.context['children'].get(obj.id, []) 
     serializer = CategoryTreeSerializer(children, many=True, context=self.context) 
     return serializer.data 


# views.py 
class CategoryViewSet(viewsets.ModelViewSet): 

    queryset = Category.objects.all() 
    serializer_class = CategoryTreeSerializer 

    @detail_route() 
    def tree(self, request, pk=None): 
     """ 
     Detail route of an category that returns it's descendants in a tree structure. 
     """ 
     category = self.get_object() 
     descendants = category.get_descendants() # add here any select_related/prefetch_related fields to improve api performance 

     children_dict = defaultdict(list) 
     for descendant in descendants: 
      children_dict[descendant.parent_id].append(descendant) 

     context = self.get_serializer_context() 
     context['children'] = children_dict 
     serializer = CategoryTreeSerializer(activity_center, context=context) 

     return Response(serializer.data) 

あなたはそれがこのようなものになります(あなたのURLに応じて)新しいエンドポイントを取得:するcategory/<category_pk>/tree指定されたカテゴリのツリー構造を取得します。

アイデアは、すべての子孫を取得し、複数のクエリを避けるためにシリアライザのコンテキストに渡される各親に対してchildren_dictを設定することです。

+0

あなたが言ったように何かを得ることができるように見えます。私はほとんどそこに着いた。今私はもう少し努力をしています。 – diogosimao

関連する問題