सूची में कई-कई प्रदर्शन django


91
class PurchaseOrder(models.Model):
    product = models.ManyToManyField('Product')
    vendor = models.ForeignKey('VendorProfile')
    dollar_amount = models.FloatField(verbose_name='Price')


class Product(models.Model):
   products = models.CharField(max_length=256)

   def __unicode__(self):
       return self.products

मेरे पास वह कोड है। दुर्भाग्य से, व्यवस्थापक के साथ admin.py में त्रुटि आती हैManyToManyField

class PurchaseOrderAdmin(admin.ModelAdmin):
    fields = ['product', 'dollar_amount']
    list_display = ('product', 'vendor')

त्रुटि कहती है:

'PurchaseOrderAdmin.list_display [0]', 'उत्पाद' एक ManyToManyField है जो समर्थित नहीं है।

हालाँकि, यह संकलित करता है जब मैं 'product'बाहर निकालता हूं list_display। तो मैं कैसे प्रदर्शित कर सकते हैं 'product'में list_displayयह त्रुटियों दिए बिना?

संपादित करें : शायद एक बेहतर सवाल यह है कि आप एक को प्रदर्शित करते होगी ManyToManyFieldमें list_display?

जवाबों:


171

आप इसे सीधे करने में सक्षम नहीं हो सकते हैं। के प्रलेखन सेlist_display

ManyToManyField फ़ील्ड्स समर्थित नहीं हैं, क्योंकि यह तालिका में प्रत्येक पंक्ति के लिए एक अलग SQL कथन निष्पादित करेगा। यदि आप इसे फिर भी करना चाहते हैं, तो अपने मॉडल को एक कस्टम विधि दें, और उस विधि का नाम list_display में जोड़ें। (List_display में कस्टम तरीकों के बारे में अधिक जानने के लिए नीचे देखें।)

आप ऐसा कुछ कर सकते हैं:

class PurchaseOrderAdmin(admin.ModelAdmin):
    fields = ['product', 'dollar_amount']
    list_display = ('get_products', 'vendor')

    def get_products(self, obj):
        return "\n".join([p.products for p in obj.product.all()])

या एक मॉडल विधि को परिभाषित करें, और इसका उपयोग करें

class PurchaseOrder(models.Model):
    product = models.ManyToManyField('Product')
    vendor = models.ForeignKey('VendorProfile')
    dollar_amount = models.FloatField(verbose_name='Price')

    def get_products(self):
        return "\n".join([p.products for p in self.product.all()])

और व्यवस्थापक में list_display

list_display = ('get_products', 'vendor')

यह एक बहुत अच्छा समाधान की तरह लग रहा है। धन्यवाद। हालाँकि, मुझे अब यह कहते हुए एक त्रुटि हो रही है कि "कॉलम में शून्य मान" product_id "नॉट-नल बाधा का उल्लंघन करता है" किसी भी विचार का क्या अर्थ है?
Mdjon26

3
चूंकि यह डेटाबेस को अपने घुटनों तक लाता है, आप प्रदर्शन में सुधार के लिए इसे select_related () या prefetch_related () के साथ कैसे करेंगे?
मेघ कारीगर

3
बस के मामले में अनुकूलन सवाल अभी भी दिलचस्प है, मुझे बस एक ही समस्या थी और पता चला कि आप बस get_queryset()अपने लिए एक अनुकूलित पद्धति लागू कर सकते हैं ModelAdmin, देखें stackoverflow.com/questions/12354099/…
goetz

1
@ सेबस्टियनवैनस्टीनकिस्ट अच्छा विचार, शायद cached_propertyमदद करेगा। लेकिन मुझे लगता है कि यह शायद नहीं होगा। जब आप एक अनुकूलित का उपयोग करते हैं get_queryset, तो आप उदाहरण के लिए डेटा को एनोटेट / पूर्व-संसाधित कर सकते हैं, जैसे कि Django के बजाय SQL में उत्पादों का संघटन करना और अपने क्वेरी में अपने कस्टम डेटा को संग्रहीत करना। तब आपको केवल उस तर्क को SQL में एक बार निष्पादित करने की आवश्यकता होगी और संपत्ति के एक्सेस होने पर हर पंक्ति के लिए नहीं।
goetz

1
अच्छी बात। मुझे स्वयं को अनुकूलित करते हुए देखना चाहिए get_queryset, मुझे अभी पूरा डॉक्स पढ़ने के लिए नहीं मिला है (और न ही मुझे क्या करना चाहिए इसका एक सरल पर्याप्त उदाहरण मिला)
सेबस्टियन वनस्टीनिस्टिस्ट

16

इस तरह से आप इसे कर सकते हैं, कृपया निम्नलिखित स्निपेट देखें:

class Categories(models.Model):
    """ Base category model class """

    title       = models.CharField(max_length=100)
    description = models.TextField()
    parent      = models.ManyToManyField('self', default=None, blank=True)
    when        = models.DateTimeField('date created', auto_now_add=True)

    def get_parents(self):
        return ",".join([str(p) for p in self.parent.all()])

    def __unicode__(self):
        return "{0}".format(self.title)

और आपके admin.py मॉड्यूल कॉल विधि इस प्रकार है:

class categories(admin.ModelAdmin):
    list_display    = ('title', 'get_parents', 'when')
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.