web-dev-qa-db-fra.com

plusieurs à plusieurs dans l'affichage de la liste django

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

J'ai ce code. Malheureusement, l'erreur vient dans admin.py avec le ManyToManyField

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

L'erreur dit:

'PurchaseOrderAdmin.list_display [0]', 'produit' est un ManyToManyField qui n'est pas pris en charge.

Cependant, il se compile lorsque je prends 'product' hors de list_display. Alors, comment puis-je afficher 'product' dans list_display sans lui donner d'erreurs?

edit: Peut-être une meilleure question serait de savoir comment afficher un ManyToManyField dans list_display?

66
Mdjon26

Vous ne pourrez peut-être pas le faire directement. D'après la documentation de list_display

Les champs ManyToManyField ne sont pas pris en charge, car cela impliquerait l'exécution d'une instruction SQL distincte pour chaque ligne de la table. Si vous souhaitez néanmoins le faire, donnez à votre modèle une méthode personnalisée et ajoutez le nom de cette méthode à list_display. (Voir ci-dessous pour plus d'informations sur les méthodes personnalisées dans list_display.)

Vous pouvez faire quelque chose comme ça:

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

OU définir une méthode de modèle, et l'utiliser

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

et dans l'admin list_display

list_display = ('get_products', 'vendor')
130
karthikr

De cette façon, vous pouvez le faire, veuillez vérifier l'extrait de code suivant:

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)

Et dans votre méthode d'appel de module admin.py comme suit:

class categories(admin.ModelAdmin):
    list_display    = ('title', 'get_parents', 'when')
10
JKV