2016-01-17 4 views
9

साथ tastypie के प्रश्नों में तेजी लाने के resources.py में मेरे पास है:कैसे ToManyField

class CategoryResource(ModelResource): 
    items = fields.ToManyField('ItemResource', 'items', full=True, null=False, readonly=True, related_name='items') 
    class Meta: 
     queryset = Category.objects.all().order_by('id') 
     include_resource_uri = False 
     always_return_data = True 
     resource_name = 'category' 

6 श्रेणियों में के बारे में 5000 आइटम नहीं है। जब मैं 'सूची' एपीआई अनुरोध बना देता हूं i.e. 'api/1.0/category', यह डेटाबेस के लिए लगभग 5000 प्रश्न बनाता है। मैं इसे कैसे अनुकूलित कर सकता हूं? मैं पूर्ण = गलत के बारे में जानता हूं, लेकिन यह मेरी ज़रूरतों के अनुरूप नहीं है।

यूपीडी: मुझे पता चला कि इतने सारे प्रश्न क्या हैं। मेरे पास ItemResource में 'श्रेणियां' संबंध हैं, इसलिए स्वादिष्ट प्रत्येक आइटम के लिए एक चुनिंदा क्वेरी उत्पन्न करते हैं।

class ItemResource(ModelResource): 
    categories = fields.ToManyField(CategoryResource, 'categories', null=True, readonly=True) 

    def dehydrate_categories(self, bundle): 
     categories = Category.objects.filter(owner_id=bundle.request.user.id, items__item=bundle.obj) 
     return [category.name for category in categories] 

जाहिर है कि अनावश्यक डेटा है जब मैं एक CategoryResource का अनुरोध, वहाँ प्रश्नों से बाहर करने के लिए कोई तरीका है?

उत्तर

3

इस प्रयास करें:

def get_object_list(self, request): 
    return super(CategoryResource, self).get_object_list(request) \ 
     .prefetch_related('items', 'items__categories') 

, select_related का उपयोग न करें, क्योंकि यह डुप्लिकेट पंक्तियों को वापस।

prefetch_related एक प्रश्न बना दिया, जो सभी आइटम लौटाता है और Django ORM इसे उचित पंक्तियों से मेल खाता है।

संपादित

बदलें dehydrate_categories

def dehydrate_categories(self, bundle): 
    return [category.name for category in bundle.obj.categories.all() if category.owner == bundle.request.user] 
+0

मेरे लिए काम नहीं करते - सभी एक ही रहें – svfat

+1

'आइटम रिसोर्स' और मॉडल –

+0

दिखाएं संपादित करें: इसलिए मेरे स्वरूपण को गड़बड़ कर दिया गया, इसलिए मैंने एक और जवाब के रूप में दोबारा पोस्ट किया। | यदि अभी भी कोई समस्या है, तो यह हो सकता है कि ItemResource में एक या अधिक संबंधित फ़ील्ड भी हों। डीईएफ़ get_object_list (स्वयं, अनुरोध) : अगर ऐसी बात है, तो आप शायद की तरह कुछ कर सकते हैं वापसी सुपर (CategoryResource, आत्म) .get_object_list (अनुरोध) .prefetch_related ('items__relatedfield1', 'items__relatedfield2') रखें दिमाग, 'itemResource' पर किए गए 'select_related' या' prefetch_related जैसे किसी भी क्वेरीसेट परिवर्तन 'श्रेणी संसाधन' पर संबंधित मॉडल के लिए क्वेरी को प्रभावित नहीं करेंगे। –

2

अगर वहाँ अभी भी एक समस्या है, यह हो सकता है ItemResource भी एक या अधिक संबंधित क्षेत्रों है। अगर ऐसी बात है, तो आप शायद की तरह कुछ कर सकते हैं: ध्यान रखें

def get_object_list(self, request): 
    return super(CategoryResource, self).get_object_list(request).prefetch_related('items__relatedfield1', 'items__relatedfield2') 

, किसी भी क्वेरीसमूह परिवर्तन जैसे select_related या prefetch_relatedItemResource पर प्रदर्शन CategoryResource पर संबंधित मॉडल के लिए क्वेरी को प्रभावित नहीं करेगा।

अद्यतन: इस तरह प्रयास करें कुछ:

class CategoryResource(ModelResource): 
    items = fields.ToManyField('ItemResource', 'items', full=True, null=False, readonly=True, related_name='items') 

    class Meta: 
     queryset = Category.objects.all().order_by('id') 
     include_resource_uri = False 
     always_return_data = True 
     resource_name = 'category' 

    def get_object_list(self, request): 
     return super(CategoryResource, self).get_object_list(request) \ 
      .prefetch_related('items', 'items__categories') 

class ItemResource(ModelResource): 
    categories = fields.ToManyField(CategoryResource, 'categories', null=True, readonly=True) 

    def dehydrate_categories(self, bundle): 
     categories = items__item=bundle.obj.categories.all() 
     return [ 
      category.name 
      for category in categories 
      if category.owner_id == bundle.request.user.id 
     ] 

या:

class CategoryResource(ModelResource): 
    items = fields.ToManyField('ItemResource', 'items', full=True, null=False, readonly=True, related_name='items') 

    class Meta: 
     queryset = Category.objects.all().order_by('id') 
     include_resource_uri = False 
     always_return_data = True 
     resource_name = 'category' 

    def get_object_list(self, request): 
     return super(CategoryResource, self).get_object_list(request) \ 
      .prefetch_related(
       'items', 
       Prefetch('items__categories', queryset=Category.objects.filter(owner_id=bundle.request.user.id)) 
      ) 

class ItemResource(ModelResource): 
    categories = fields.ToManyField(CategoryResource, 'categories', null=True, readonly=True) 

    def get_object_list(self, request): 
     return super(ItemResource, self).get_object_list(request) \ 
      .prefetch_related(
       Prefetch('categories', queryset=Category.objects.filter(owner_id=bundle.request.user.id)) 
      ) 

    def dehydrate_categories(self, bundle): 
     return [ 
      category.name 
      for category in bundle.obj.categories.all() 
     ] 

इसके अलावा, आप शायद ItemResource.categories के बाद से आप मैन्युअल रूप से संभाल रहे हैं के लिए ToManyField के बजाय एक ListField उपयोग कर सकते हैं निर्जलीकरण।

+0

कृपया यूपीडी – svfat

+0

देखें" मुझे आइटम ऑब्जेक्ट में कोई विशेषता नहीं है 'श्रेणियां' त्रुटि – svfat

+1

इसके बजाय category_set आज़माएं। मुझे आपके द्वारा प्रदान किए गए कोड से "item.categories" मिल गया है। –