如何将外键列添加到 dj-stripe admin?

How to add foreign-key column to dj-stripe admin?

我想将计划名称添加到 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)

...

产生此错误的原因:

Subscription has no field named 'plan__product__name'

如何在 dj-stripe 中添加需要外键查找的额外列?

一个解决方案是创建一个可调用对象,然后在模型管理中引用它 class。

根据 docs:

ModelAdmin.list_display

Set list_display to control which fields are displayed on the change list page of the admin.

There are four types of values that can be used in list_display. All but the simplest may use the display() decorator is used to customize how the field is presented:

A callable that accepts one argument, the model instance. For example:

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