2013-02-12 13 views
18

मैं django और django-rest-framework का उपयोग कर सभी जेसन प्रतिक्रियाओं में रूट तत्व जोड़ने का सबसे अच्छा तरीका निर्धारित करने का प्रयास कर रहा हूं।जेसन प्रतिक्रिया (डीजेंगो-रेस्ट-फ्रेमवर्क) में रूट तत्व जोड़ना

मैं एक कस्टम रेंडरर जोड़ने लगता है कि सबसे अच्छा तरीका है पूरा करने के लिए मैं क्या हासिल करना चाहते है और यह है कि क्या मैं अब तक के साथ आए हैं है:

from rest_framework.renderers import JSONRenderer 

class CustomJSONRenderer(JSONRenderer): 
#override the render method 
def render(self, data, accepted_media_type=None, renderer_context=None): 
    #call super, as we really just want to mess with the data returned 
    json_str = super(CustomJSONRenderer, self).render(data, accepted_media_type, renderer_context) 
    root_element = 'contact' 

    #wrap the json string in the desired root element 
    ret = '{%s: %s}' % (root_element, json_str) 

    return ret 

मुश्किल हिस्सा अब गतिशील root_element स्थापित कर रही है आधारित इस विचार पर कि render() से कहा जा रहा है।

किसी भी संकेत दिए गए/सलाह बहुत सराहना की जाएगी,

चीयर्स

उत्तर

13

भावी पीढ़ी के लिए, नीचे अंतिम समाधान है। यह मूल से थोड़ी बढ़ी है क्योंकि अब यह पेजिनेटेड परिणामों को भी सुधारता है।

इसके अलावा मुझे पहले निर्दिष्ट करना चाहिए था कि JSON रूट तत्व का कारण एम्बर फ्रंट एंड समाधान के साथ एकीकरण के लिए है।

serializer:

from rest_framework.serializers import ModelSerializer 
from api.models import Contact 

class ContactSerializer(ModelSerializer): 
    class Meta: 
     model = Contact 
     #define the resource we wish to use for the root element of the response 
     resource_name = 'contact' 
     fields = ('id', 'first_name', 'last_name', 'phone_number', 'company') 

रेंडरर:

from rest_framework.renderers import JSONRenderer 

class CustomJSONRenderer(JSONRenderer): 
    """ 
     Override the render method of the django rest framework JSONRenderer to allow the following: 
     * adding a resource_name root element to all GET requests formatted with JSON 
     * reformatting paginated results to the following structure {meta: {}, resource_name: [{},{}]} 

     NB: This solution requires a custom pagination serializer and an attribute of 'resource_name' 
     defined in the serializer 
    """ 
    def render(self, data, accepted_media_type=None, renderer_context=None): 
     response_data = {} 

     #determine the resource name for this request - default to objects if not defined 
     resource = getattr(renderer_context.get('view').get_serializer().Meta, 'resource_name', 'objects') 

     #check if the results have been paginated 
     if data.get('paginated_results'): 
      #add the resource key and copy the results 
      response_data['meta'] = data.get('meta') 
      response_data[resource] = data.get('paginated_results') 
     else: 
      response_data[resource] = data 

     #call super to render the response 
     response = super(CustomJSONRenderer, self).render(response_data, accepted_media_type, renderer_context) 

     return response 

पृष्ठांकन: मुझे वहाँ रास्ते से 95% प्राप्त करने के लिए ever.wakeful को

from rest_framework import pagination, serializers 

class CustomMetaSerializer(serializers.Serializer): 
    next_page = pagination.NextPageField(source='*') 
    prev_page = pagination.PreviousPageField(source='*') 
    record_count = serializers.Field(source='paginator.count') 

class CustomPaginationSerializer(pagination.BasePaginationSerializer): 
    # Takes the page object as the source 
    meta = CustomMetaSerializer(source='*') 
    results_field = 'paginated_results' 
+0

धन्यवाद एक विचार के लिए ever.wakeful, मैं भी मैं इसे कैसे ExtJs दृश्यपटल के साथ उपयोग के बारे में पोस्ट लिखा (वहां मुझे मूल तत्व को अलग-अलग कॉल करने की आवश्यकता नहीं है। और मुझे रूट तत्व के अंदर paginator.count होना चाहिए) http://kaygorodov.github.io/2014/02/21/extjs-django-rest-framework -root-element.html –

5

क्रेडिट।

व्यक्तिगत रूप से, मैं किसी निश्चित वस्तु के लिए प्रत्येक एपीआई अनुरोध में मेटा डेटा जोड़ना चाहता था, भले ही इसे पृष्ठांकित किया गया हो या नहीं। मैं बस एक dict ऑब्जेक्ट में पास करना चाहता था जिसे मैंने मैन्युअल रूप से परिभाषित किया था।

ट्वीक कस्टम रेंडरर

class CustomJSONRenderer(renderers.JSONRenderer): 
    def render(self, data, accepted_media_type=None, renderer_context=None): 
     response_data = {} 
     # Name the object list 
     object_list = 'results' 
     try: 
      meta_dict = getattr(renderer_context.get('view').get_serializer().Meta, 'meta_dict') 
     except: 
      meta_dict = dict() 
     try: 
      data.get('paginated_results') 
      response_data['meta'] = data['meta'] 
      response_data[object_list] = data['results'] 
     except: 
      response_data[object_list] = data 
      response_data['meta'] = dict() 
      # Add custom meta data 
      response_data['meta'].update(meta_dict) 
      # Call super to render the response 
      response = super(CustomJSONRenderer, self).render(response_data, accepted_media_type, renderer_context) 
     return response 

जनक Serializer और देखें उदाहरण

class MovieListSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Movie 
     meta_dict = dict() 
     meta_dict['foo'] = 'bar' 

class MovieViewSet(generics.ListAPIView): 
    queryset = Movie.objects.exclude(image__exact = "") 
    serializer_class = MovieListSerializer 
    permission_classes = (IsAdminOrReadOnly,) 
    renderer_classes = (CustomJSONRenderer,) 
    pagination_serializer_class = CustomPaginationSerializer 
    paginate_by = 10 
+0

क्या यह मेटा_डिक्ट का उपयोग मूल्य से पास करने के लिए करना संभव है, मैं meta_dict में request.user को पास करना चाहता हूं –

संबंधित मुद्दे