programing

Django ModelAdmin의 list_display는 ForeignKey 필드의 속성을 표시할 수 있습니까?

bestcode 2023. 1. 12. 22:13
반응형

Django ModelAdmin의 list_display는 ForeignKey 필드의 속성을 표시할 수 있습니까?

는 나나 a a a가 있다Person 키 .Book는 가장 되는 것은 이 필드입니다author(CharField).

그 말이 나와서 말인데, 내 말은,PersonAdmin델,, 시시합합 model model model model model이다를 전시하고 싶습니다.book.author를 사용합니다.list_display:

class PersonAdmin(admin.ModelAdmin):
    list_display = ['book.author',]

모든 명백한 방법을 시도해 봤지만 효과가 없는 것 같아요.

좋은 의견이라도 있나?

다른 옵션으로는 다음과 같은 조회를 수행할 수 있습니다.

class UserAdmin(admin.ModelAdmin):
    list_display = (..., 'get_author')
    
    def get_author(self, obj):
        return obj.book.author
    get_author.short_description = 'Author'
    get_author.admin_order_field = 'book__author'

Django 3.2이므로 데코레이터를 사용할 수 있습니다.

class UserAdmin(admin.ModelAdmin):
    list_display = (..., 'get_author')
    
    @display(ordering='book__author', description='Author')
    def get_author(self, obj):
        return obj.book.author

위의 모든 훌륭한 답변에도 불구하고, 그리고 장고에 처음 온 덕분에, 나는 여전히 꼼짝할 수 없었다.아주 초보적인 관점에서 설명하겠습니다.

models.py

class Author(models.Model):
    name = models.CharField(max_length=255)

class Book(models.Model):
    author = models.ForeignKey(Author)
    title = models.CharField(max_length=255)

admin.py (잘못된 방법) - 'model__field'를 사용하여 참조할 수 있다고 생각하지만 그렇지 않습니다.

class BookAdmin(admin.ModelAdmin):
    model = Book
    list_display = ['title', 'author__name', ]

admin.site.register(Book, BookAdmin)

admin.py (올바른 방법) - 외부 키 이름을 Django 방식으로 참조하는 방법입니다.

class BookAdmin(admin.ModelAdmin):
    model = Book
    list_display = ['title', 'get_name', ]

    def get_name(self, obj):
        return obj.author.name
    get_name.admin_order_field  = 'author'  #Allows column order sorting
    get_name.short_description = 'Author Name'  #Renames column head

    #Filtering on side - for some reason, this works
    #list_filter = ['title', 'author__name']

admin.site.register(Book, BookAdmin)

자세한 내용은 여기를 참조해 주세요.

다른 사람들과 마찬가지로 저도 캘러블을 사용했어요.하지만 한 가지 단점이 있습니다. 기본적으로는 주문하실 수 없습니다.다행히 이에 대한 해결책이 있습니다.

장고 > = 1.8

def author(self, obj):
    return obj.book.author
author.admin_order_field  = 'book__author'

장고 < 1 . 8

def author(self):
    return self.book.author
author.admin_order_field  = 'book__author'

★★★★★★★★★★★를 추가하는 것에 주의해 .get_author각 사용자를 표시하면 SQL 쿼리가 생성되기 때문에 관리자에 list_display가 느려집니다.

.get_queryset[ Person Admin ] 를adminadmin의 。

def get_queryset(self, request):
    return super(PersonAdmin,self).get_queryset(request).select_related('book')

이전 버전: 36.02ms 동안 73개의 쿼리(admin에서 67개의 중복된 쿼리)

이후: 10.81ms 동안 6개의 쿼리

장고 > = 3.2의 경우

Django 3.2 이상을 사용하는 적절한 방법은 디스플레이 데코레이터를 사용하는 것입니다.

class BookAdmin(admin.ModelAdmin):
    model = Book
    list_display = ['title', 'get_author_name']

    @admin.display(description='Author Name', ordering='author__name')
    def get_author_name(self, obj):
        return obj.author.name

할 수 것은 「」입니다.__unicode__ForeignKey 현: :

http://docs.djangoproject.com/en/dev/ref/contrib/admin/ #list-display

the the the the the the the the the the the the the the the the the the the 를 지원하지 않는 것이 'book__author'DB API를 사용합니다.

기능에 대한 티켓이 있으며, 이 티켓은 수정 안 함으로 표시되어 있습니다.

방금 관리인을 만드는 기사를 올렸어요Model Admin은 '__' 구문을 지원합니다.

http://djangosnippets.org/snippets/2887/

다음과 같은 작업을 수행할 수 있습니다.

class PersonAdmin(RelatedFieldAdmin):
    list_display = ['book__author',]

이는 기본적으로 다른 답변에서 설명한 것과 동일한 작업을 수행하지만 (1) admin_order_field 설정 (2) short_description 설정 (3) 각 행에 대한 데이터베이스 히트를 피하기 위해 쿼리셋을 자동으로 변경합니다.

콜 가능을 사용하면 목록 표시에 원하는 내용을 표시할 수 있습니다.다음과 같습니다.


def book_author(개체):
object.book을 반환합니다.작가.
클래스 PersonAdmin(admin).모델 관리자):
list_display = [book_author, ]

PyPI에서는 매우 사용하기 쉬운 패키지가 제공되고 있습니다.이 패키지는 django-related-admin 입니다.GitHub에서도 코드를 볼 수 있습니다.

이를 통해 달성하고자 하는 것은 다음과 같습니다.

class PersonAdmin(RelatedFieldAdmin):
    list_display = ['book__author',]

두 링크 모두 설치 및 사용 방법에 대한 자세한 내용이 포함되어 있으므로 변경 시 여기에 붙여넣지 않습니다.

참고로, 이미 다른 것을 사용하고 있다면model.Admin( ( )을 사용하고 )SimpleHistoryAdmin 이렇게 돼요.class MyAdmin(SimpleHistoryAdmin, RelatedFieldAdmin).

이것은 이미 인정되고 있습니다만, (저와 같이) 현재 인정되고 있는 답변에서 바로 알 수 없는 바보가 있다면, 여기 좀 더 자세히 설명하겠습니다.

에서 ForeignKey needs a가 필요합니다.__unicode__안에 ,를 들면 다음과 .

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

    def __unicode__(self):
        return self.name

그것이 나에게 차이를 가져왔고, 위의 시나리오에도 적용될 것이다.이것은 장고 1.0.2에서 동작합니다.

에서 list_display 속성)을 더러우면서도 합니다.ModelAdmin__getattr__.

class DynamicLookupMixin(object):
    '''
    a mixin to add dynamic callable attributes like 'book__author' which
    return a function that return the instance.book.author value
    '''

    def __getattr__(self, attr):
        if ('__' in attr
            and not attr.startswith('_')
            and not attr.endswith('_boolean')
            and not attr.endswith('_short_description')):

            def dyn_lookup(instance):
                # traverse all __ lookups
                return reduce(lambda parent, child: getattr(parent, child),
                              attr.split('__'),
                              instance)

            # get admin_order_field, boolean and short_description
            dyn_lookup.admin_order_field = attr
            dyn_lookup.boolean = getattr(self, '{}_boolean'.format(attr), False)
            dyn_lookup.short_description = getattr(
                self, '{}_short_description'.format(attr),
                attr.replace('_', ' ').capitalize())

            return dyn_lookup

        # not dynamic lookup, default behaviour
        return self.__getattribute__(attr)


# use examples    

@admin.register(models.Person)
class PersonAdmin(admin.ModelAdmin, DynamicLookupMixin):
    list_display = ['book__author', 'book__publisher__name',
                    'book__publisher__country']

    # custom short description
    book__publisher__country_short_description = 'Publisher Country'


@admin.register(models.Product)
class ProductAdmin(admin.ModelAdmin, DynamicLookupMixin):
    list_display = ('name', 'category__is_new')

    # to show as boolean field
    category__is_new_boolean = True

여기서의 요지로

「」의 콜 가능한 .boolean ★★★★★★★★★★★★★★★★★」short_description.ModelAdmin: " " )book__author_verbose_name = 'Author name' ★★★★★★★★★★★★★★★★★」category__is_new_boolean = True.

가능한 theadmin_order_field아트리뷰트

list_select_related 속성을 사용하는 것을 잊지 마십시오.ModelAdmin장고가 상투적인 질문을 피하게 하기 위해서.

인라인에서 시도하면 다음 조건이 충족되지 않습니다.

인라인:

class AddInline(admin.TabularInline):
    readonly_fields = ['localname',]
    model = MyModel
    fields = ('localname',)

모델(MyModel):

class MyModel(models.Model):
    localization = models.ForeignKey(Localizations)

    def localname(self):
        return self.localization.name

늦을지도 모르지만, 이것은 다른 방법이다.하고, 「메서드」를 통해 할 수 .list_display음음음같 뭇매하다

models.py

class Person(models.Model):
    book = models.ForeignKey(Book, on_delete=models.CASCADE)

    def get_book_author(self):
        return self.book.author

admin.py

class PersonAdmin(admin.ModelAdmin):
    list_display = ('get_book_author',)

단, 위의 접근방법 및 기타 접근방법에서는 listview페이지에서 행당2개의 쿼리가 추가됩니다.하려면 , 「」, 「」를 수 .get_queryset필드에 을 달려면 합니다.

admin.py

from django.db.models.expressions import F

@admin.register(models.Person)
class PersonAdmin(admin.ModelAdmin):
    list_display = ('get_author',)
    def get_queryset(self, request):
        queryset = super().get_queryset(request)
        queryset = queryset.annotate(
            _author = F('book__author')
        )
        return queryset

    @admin.display(ordering='_author', description='Author')
    def get_author(self, obj):
        return obj._author

Alex Robbins의 답변은 효과가 있었습니다.단, 첫 번째 두 줄은 모델에 포함되어 있어야 합니다(아마도 이것이 상정되어 있을 것입니다).또, 자기 자신을 참조할 필요가 있습니다.

def book_author(self):
  return self.book.author

그러면 admin 파트가 잘 동작합니다.

나는 이것을 선호한다:

class CoolAdmin(admin.ModelAdmin):
    list_display = ('pk', 'submodel__field')

    @staticmethod
    def submodel__field(obj):
        return obj.submodel.field

언급URL : https://stackoverflow.com/questions/163823/can-list-display-in-a-django-modeladmin-display-attributes-of-foreignkey-field

반응형