it-source

장고 관리자에서 "list_display"로 다대다 필드를 표시하는 방법은 무엇입니까?

criticalcode 2023. 8. 19. 10:25
반응형

장고 관리자에서 "list_display"로 다대다 필드를 표시하는 방법은 무엇입니까?

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')

그 코드를 가지고 있습니다.안타깝게도 admin에서 오류가 발생합니다.에 열중하는.ManyToManyField

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

다음 오류가 발생합니다.

'PurchaseOrderAdmin.list_display[0]', 'product'는 지원되지 않는 ManyToManyField입니다.

하지만, 제가 찍으면 컴파일이 됩니다.'product'밖으로list_display그래서 어떻게 표시합니까?'product'list_display오류를 주지 않고요?

편집: 더 나은 질문은 어떻게 표시하느냐입니다.ManyToManyFieldlist_display?

당신은 그것을 직접 하지 못할 수도 있습니다.의 문서에서.

테이블의 각 행에 대해 별도의 SQL 문을 실행해야 하므로 많은 ToManyField 필드가 지원되지 않습니다.그래도 이 작업을 수행하려면 모델에 사용자 지정 메서드를 지정하고 해당 메서드의 이름을 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')

이렇게 하면 다음 스니펫을 확인할 수 있습니다.

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')

추가 쿼리를 저장하려면 에서 prefetch_related를 사용할 수 있습니다.get_queryset아래와 같은 방법:

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

Docs에 따르면, 이런 방식으로 관련 정보를 가져오는 데 필요한 추가 쿼리가 하나 있습니다.Product모두의 항목PurchaseOrder각각 하나의 쿼리가 필요하지 않은 인스턴스PurchaseOrder사례.

예를 들어, 다음과 같은 것들이 있습니다.Category그리고.Product다대다 관계가 있는 모델은 아래와 같습니다.*장고 4.2.1을 사용합니다.

# "models.py"

from django.db import models

class Category(models.Model):
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.name

class Product(models.Model):
    categories = models.ManyToManyField(Category)
    name = models.CharField(max_length=50)
    price = models.DecimalField(decimal_places=2, max_digits=5)

그리고 또 있습니다.Category그리고.Product관리자는 다음과 같습니다.

from django.contrib import admin
from .models import Category, Product

@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    list_display = ('id', 'name')
    ordering = ('id',)

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ('id', 'name', 'price')
    ordering = ('id',)

그리고나서,Categoryadmin에는 아래와 같이 5개의 개체가 있습니다.

enter image description here

그리고.Productadmin에는 아래와 같이 6개의 개체가 있습니다.

enter image description here

이제 정의합니다.get_products그리고.get_categories()@admin.display를 사용하여 list_display in으로 설정합니다.Category그리고.Product관리자는 아래와 같이 각각 관리합니다. *description에 있어서의 논쟁.@admin.display()Django Admin의 열 이름을 변경할 수 있습니다.GET PRODUCTS그리고.GET CATEGORIES로.PRODUCTS그리고.CATEGORIES각각:

# "admin.py"

@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    list_display = ('id', 'name', 'get_products')
    ordering = ('id',)            # Here

    # Here
    @admin.display(description='products')
    def get_products(self, obj):
        return [product.name for product in obj.product_set.all()]

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):      # Here  
    list_display = ('id', 'name', 'price', 'get_categories')
    ordering = ('id',)
    
    # Here
    @admin.display(description='categories')
    def get_categories(self, obj):
        return [category.name for category in obj.categories.all()]

그리고나서,PRODUCTS열이 표시됩니다.Category관리자는 아래와 같습니다.

enter image description here

그리고나서,CATEGORIES열이 표시됩니다.Product관리자는 아래와 같습니다.

enter image description here

또한 표시할 수 있습니다.PRODUCTS그리고.CATEGORIES정의에 의한 열get_products()그리고.get_categories()와 함께@admin.display()Category그리고.Product각각 아래와 같은 모델:

# "models.py"

from django.db import models
from django.contrib import admin

class Category(models.Model):
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.name

    # Here
    @admin.display(description='products')
    def get_products(self):
        return [product.name for product in self.product_set.all()]

class Product(models.Model):
    categories = models.ManyToManyField(Category)
    name = models.CharField(max_length=50)
    price = models.DecimalField(decimal_places=2, max_digits=5)

    # Here
    @admin.display(description='categories')
    def get_categories(self):
        return [category.name for category in self.categories.all()]

다음으로 설정합니다.list_displayCategory그리고.Product관리자는 아래와 같이 각각 관리합니다.

# "admin.py"

...

@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    list_display = ('id', 'name', 'get_products')
    ordering = ('id',)            # Here

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):      # Here
    list_display = ('id', 'name', 'price', 'get_categories')
    ordering = ('id',)

언급URL : https://stackoverflow.com/questions/18108521/how-to-show-a-many-to-many-field-with-list-display-in-django-admin

반응형