2012-12-07 15 views
5

के माध्यम से मैं एक परियोजना के लिए एक एपीआई पर काम कर रहा हूँ के साथ एक संसाधन होने ManytoMany क्षेत्र पर पोस्ट और मैं इस तरह OrderProducts के माध्यम से एक रिश्ता आदेश/उत्पाद है:Django-tastypie: रिश्ते

models.py

में
class Product(models.Model): 
    ... 

class Order(models.Model): 
    products = models.ManyToManyField(Product, verbose_name='Products', through='OrderProducts') 
    ... 

class OrderProducts(models.Model): 
    order = models.ForeignKey(Order) 
    product = models.ForeignKey(Product) 
    ... 

अब, जब मैं एपीआई के माध्यम से एक आदेश लोड मैं भी संबंधित उत्पाद प्राप्त करना चाहते हैं, तो मैं (Django-tastypie के साथ) इस कोशिश की:

आदेश/api.py में

class OrderResource(ModelResource): 
    products = fields.ToManyField('order.api.ProductResource', products, full=True) 

    class Meta: 
     queryset = Order.objects.all() 
     resource_name = 'order' 

सबकुछ ऑर्डर संसाधनों को सूचीबद्ध करने के लिए काम करता है। मुझे एम्बेडेड उत्पाद डेटा के साथ ऑर्डर संसाधन मिलते हैं।

समस्या यह है कि मैं एपीआई का उपयोग कर ऑर्डर ऑब्जेक्ट्स बनाने या संपादित करने में सक्षम नहीं हूं। चूंकि मैं कईtoMany संबंध में मॉडल के माध्यम से उपयोग कर रहा हूं, ManyToManyField (उत्पादों) में .add() विधियां नहीं हैं। लेकिन tastypie ऑर्डर रिसोर्स में उत्पाद फ़ील्ड पर डेटा को पोस्ट/डालने पर .add() को कॉल करने का प्रयास कर रहा है।

{"error_message": "'ManyRelatedManager' object has no attribute 'add'", "traceback": "Traceback (most recent call last):\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 192, in wrapper\n response = callback(request, *args, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 397, in dispatch_list\n return self.dispatch('list', request, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 427, in dispatch\n response = method(request, **kwargs)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 1165, in post_list\n updated_bundle = self.obj_create(bundle, request=request, **self.remove_api_resource_names(kwargs))\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 1784, in obj_create\n self.save_m2m(m2m_bundle)\n\n File \"/Library/Python/2.7/site-packages/tastypie/resources.py\", line 1954, in save_m2m\n related_mngr.add(*related_objs)\n\nAttributeError: 'ManyRelatedManager' object has no attribute 'add'\n"} 
+0

यह प्रश्न आपकी मदद कर सकता है: http://stackoverflow.com/questions/10629047/django-tastypie-and-many-to- कई- संबंध- संबंध – msc

उत्तर

3

समाधान संसाधन पर save_m2m() विधि को ओवरराइड करने में निहित है। मेरे मामले में मुझे केवल लिस्टिंग के लिए कई क्षेत्र की आवश्यकता थी, इसलिए कुछ भी करने के लिए save_m2m() विधि को ओवरराइड किया गया।

5

जब से तुम केवल लिस्टिंग के लिए manytomany क्षेत्र की जरूरत है, एक बेहतर समाधान OrderResource के products मैदान पर readonly=True जोड़ना है। यह save_m2m विधि को ओवरराइड करने की आवश्यकता को हटा देता है। पूर्णता के लिए:

class OrderResource(ModelResource): 
    products = fields.ToManyField('order.api.ProductResource', products, 
            readonly=True, full=True) 

    class Meta: 
     queryset = Order.objects.all() 
     resource_name = 'order' 
1

आप संशोधित करने के लिए अनुमति दी जाती है, तो auto_created = True जोड़ने आपकी समस्या, जैसे कि,

class OrderProducts(models.Model): 
    class Meta: 
     auto_created = True 

का समाधान हो सकता है आप नहीं बदल सकते हैं, तो निम्न tastypie पैच की कोशिश करो।

---------------------------- tastypie/resources.py ---------------------------- 
index 2cd869e..aadf874 100644 
@@ -2383,7 +2383,20 @@ class BaseModelResource(Resource): 
        related_resource.save(updated_related_bundle) 
       related_objs.append(updated_related_bundle.obj) 

-   related_mngr.add(*related_objs) 
+   if hasattr(related_mngr, 'through'): 
+    through = getattr(related_mngr, 'through') 
+    if not through._meta.auto_created: 
+     for related_obj in related_objs: 
+      args = dict() 
+      args[related_mngr.source_field_name] = bundle.obj 
+      args[related_mngr.target_field_name] = related_obj 
+      through_obj = through(**args) 
+      through_obj.save() 
+    else: 
+     related_mngr.add(*related_objs) 
+   else: 
+    related_mngr.add(*related_objs) 

    def detail_uri_kwargs(self, bundle_or_obj): 
     """ 

Django 1.7 में, त्रुटि संदेश "एक ManyToManyField जो एक मध्यस्थ के मॉडल को निर्दिष्ट करता है पर मूल्यों को निर्धारित नहीं कर सकते" करने के लिए बदल जाता है। समाधान वही है।