mdjon26
class Product(models.Model):
products = models.CharField(max_length=256)
def __unicode__(self):
return self.products
class PurchaseOrder(models.Model):
product = models.ManyToManyField('Product')
vendor = models.ForeignKey('VendorProfile')
dollar_amount = models.FloatField(verbose_name="Price")
yo tengo ese codigo Desafortunadamente, el error viene en admin.py con el ManyToManyField
class PurchaseOrderAdmin(admin.ModelAdmin):
fields = ['product', 'dollar_amount']
list_display = ('product', 'vendor')
El error dice:
‘OrderAdmin.list_display[0]’, ‘producto’ es un ManyToManyField que no es compatible.
Sin embargo, se compila cuando tomo 'product'
fuera de list_display
. Entonces, ¿cómo puedo mostrar 'product'
en list_display
sin dar errores?
editar: Tal vez una mejor pregunta sería ¿cómo se muestra un ManyToManyField
en list_display
?
Karthikr
Es posible que no pueda hacerlo directamente. De la documentación de list_display
Los campos ManyToManyField no son compatibles, porque eso implicaría ejecutar una instrucción SQL separada para cada fila de la tabla. No obstante, si desea hacer esto, asigne a su modelo un método personalizado y agregue el nombre de ese método a list_display. (Consulte a continuación para obtener más información sobre los métodos personalizados en list_display).
Puedes hacer algo como esto:
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()])
O definir un método de modelo y utilizarlo
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()])
y en el administrador list_display
list_display = ('get_products', 'vendor')
-
Esto parece una muy buena solución. Gracias. Aunque ahora recibo un error que dice “valor nulo en la columna” product_id “viola la restricción no nula” ¿Alguna idea de lo que esto significa?
– Mdjon26
07/08/2013 a las 16:34
-
Dado que esto pone de rodillas a la base de datos, ¿cómo lo haría con select_related() o prefetch_related() para mejorar el rendimiento?
– Artesanos de la nube
14 mayo 2017 a las 23:39
-
En caso de que la pregunta de optimización siga siendo interesante, acabo de tener el mismo problema y descubrí que simplemente podría implementar un optimizado
get_queryset()
método para suModelAdmin
consulte stackoverflow.com/questions/12354099/…– goetz
11 de julio de 2017 a las 13:45
-
@SebastiánVansteenkiste Buena idea, quizás
cached_property
ayudaría. Pero creo que probablemente no lo sería. Cuando utiliza un optimizadoget_queryset
, podría, por ejemplo, anotar/procesar previamente los datos allí, como hacer la concatenación de productos en SQL en lugar de en Django, y almacenar sus datos personalizados en su conjunto de consultas. Entonces solo necesitaría ejecutar esa lógica una vez en SQL y no para cada fila cuando se accede a la propiedad.– goetz
8 de agosto de 2019 a las 16:55
-
Buen punto. Debería considerar hacer mi propio optimizado
get_queryset
simplemente no pude leer los documentos completos (ni encontré un ejemplo lo suficientemente simple de lo que debería estar haciendo)– Sebastián Vansteenkiste
8 de agosto de 2019 a las 17:07
De esta manera puede hacerlo, por favor revise el siguiente fragmento:
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)
Y en su método de llamada de módulo admin.py de la siguiente manera:
class categories(admin.ModelAdmin):
list_display = ('title', 'get_parents', 'when')
lucas b
Si desea ahorrar consultas adicionales, puede utilizar prefetch_related en el get_queryset
método como a continuación:
class PurchaseOrderAdmin(admin.ModelAdmin):
fields = ['product', 'dollar_amount']
list_display = ('get_products', 'vendor')
def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.prefetch_related('product')
def get_products(self, obj):
return ",".join([p.products for p in obj.product.all()])
De acuerdo con la DocumentosDe esta manera, solo se necesitaría una consulta adicional para obtener Product
artículos de todos PurchaseOrder
instancias en lugar de necesitar una consulta por cada PurchaseOrder
instancia.