liste görüntüsü çoktan çoğa 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

O koda sahibim. Maalesef hata, admin.py içindeManyToManyField

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

Hata diyor ki:

'PurchaseOrderAdmin.list_display [0]', 'product' desteklenmeyen bir ManyToManyField'dir.

Ben alırken Ancak, derler 'product'dışarı list_display. Peki nasıl görüntüleyebilir 'product'içinde list_displayo hataları vermeden?

edit : Belki daha iyi bir soru, nasıl bir ManyToManyFieldin görüntülersiniz list_display?

Yanıtlar:


171

Doğrudan yapamayabilirsiniz. Belgelerindenlist_display

Tablodaki her satır için ayrı bir SQL ifadesinin yürütülmesini gerektireceğinden, ManyToManyField alanları desteklenmez. Yine de bunu yapmak istiyorsanız, modelinize özel bir yöntem verin ve bu yöntemin adını list_display'e ekleyin. (List_display'de özel yöntemler hakkında daha fazla bilgi için aşağıya bakın.)

Bunun gibi bir şey yapabilirsiniz:

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()])

VEYA bir model yöntemi tanımlayın ve bunu kullanın

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()])

ve yöneticide list_display

list_display = ('get_products', 'vendor')

Bu gerçekten iyi bir çözüm gibi görünüyor. Teşekkür ederim. Bununla birlikte, "product_id" sütunundaki boş değer "boş olmayan kısıtlamayı ihlal ediyor" diyerek bir hata alıyorum. Bunun ne anlama geldiğine dair bir fikriniz var mı?
Mdjon26

3
Bu, veritabanını dize getirdiğinden, performansı artırmak için select_related () veya prefetch_related () ile bunu nasıl yapardınız?
Cloud Artisans

3
Optimizasyon sorusunun hala ilginç olması durumunda, aynı sorunu yaşadım ve sizin için optimize edilmiş bir get_queryset()yöntemi uygulayabileceğinizi ModelAdmin
öğrendim

1
@ SebastiánVansteenkiste İyi fikir, belki cached_propertyyardımcı olabilir. Ama muhtemelen olmayacağını düşünüyorum. Optimize edilmiş bir kullandığınızda get_queryset, örneğin Django yerine SQL'de ürünlerin birleştirilmesi gibi oradaki verilere açıklama ekleyebilir / önceden işleyebilir ve özel verilerinizi sorgu kümenizde depolayabilirsiniz. Bu durumda, özelliğe erişildiğinde bu mantığı her satır için değil, SQL'de yalnızca bir kez çalıştırmanız gerekir.
goetz

1
İyi bir nokta. Kendi optimize get_querysetettiğimi yapmaya bakmalıyım , sadece tam dokümanları
okuyamadım

16

Bu şekilde bunu yapabilirsiniz, lütfen aşağıdaki pasajı kontrol edin:

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)

Ve admin.py modül çağrı yönteminizde aşağıdaki gibi:

class categories(admin.ModelAdmin):
    list_display    = ('title', 'get_parents', 'when')
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.