Как добавить колонку 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)