Как добавить колонку foreign-key в админку dj-stripe?

Я хотел бы добавить имена планов в dj-stripe django admin, чтобы я мог видеть читаемое имя для того, с чем связана каждая подписка. Добавление "cancel_at" сработало, но я не могу использовать имя продукта из плана.

В файле my_app\admin.py я делаю следующее:

from djstripe.models import Subscription
from djstripe.admin import StripeModelAdmin, SubscriptionItemInline

...

class SubscriptionAdmin(StripeModelAdmin):
    list_display = ("plan__product__name", "customer", "status", "cancel_at")
    list_filter = ("status", "cancel_at_period_end")
    list_select_related = ("customer", "customer__subscriber")
    inlines = (SubscriptionItemInline,)
    def _cancel(self, request, queryset):
        """Cancel a subscription."""
        for subscription in queryset:
            subscription.cancel()

    _cancel.short_description = "Cancel selected subscriptions"  # type: ignore # noqa
    actions = (_cancel,)


admin.site.unregister(Subscription)
admin.site.register(Subscription, SubscriptionAdmin)

...

Что приводит к такой ошибке:

У подписки нет поля с именем 'plan__product__name'

Как добавить дополнительные колонки в dj-stripe, требующие поиска внешнего ключа?

Одно из решений - сделать вызываемый класс, а затем ссылаться на него в классе modeladmin.

Согласно документам:

ModelAdmin.list_display

Установите list_display для управления тем, какие поля отображаются на странице списка изменений в админке.

Существует четыре типа значений, которые могут быть использованы в list_display. Все они, кроме самых простых, могут использовать декоратор display(), который используется для того, чтобы настроить представление поля:

Вызываемый элемент, принимающий один аргумент, экземпляр модели. Например:

@admin.display(description='Name')
    def upper_case_name(obj):
        return ("%s %s" % (obj.first_name, obj.last_name)).upper()

class PersonAdmin(admin.ModelAdmin):
    list_display = (upper_case_name,)

Что означает, что в моем случае я могу сделать следующее, чтобы добавить комбинированный столбец ярус + интервал:

@admin.display(description='Subscription Tier and Interval')
def subscription_tier_interval(obj):
    return ("%s - %s" % (obj.plan.product.name, obj.plan.interval))


class SubscriptionAdmin(StripeModelAdmin):
    list_display = ("customer", "status", subscription_tier_interval, "cancel_at")
    list_filter = ("status", "cancel_at_period_end")
    list_select_related = ("customer", "customer__subscriber")
    inlines = (SubscriptionItemInline,)
    def _cancel(self, request, queryset):
        """Cancel a subscription."""
        for subscription in queryset:
            subscription.cancel()

    _cancel.short_description = "Cancel selected subscriptions"  # type: ignore # noqa
    actions = (_cancel,)

admin.site.unregister(Subscription)
admin.site.register(Subscription, SubscriptionAdmin)
Вернуться на верх