django admin 如何在使用自定义操作按钮时添加上下文?

django admin how to add context when using custom action button?

我的管理面板中的每条记录都有一个自定义操作按钮“添加 post”。我想在上下文 obj.id 中保存以将其用作 admin:channels_post_add 形式的默认值

class ChannelAdmin(admin.ModelAdmin):
    list_display = ['title','username', 'invite_link', 'account_actions']

    def account_actions(self, obj):

        !!!! I WANT TO ADD CONTEXT HERE!!!!

        return format_html('<a class="button" href="{}">Add post</a>', reverse('admin:channels_post_add'))

    account_actions.short_description = 'Actions'
    account_actions.allow_tags = True

    class Meta:
        model = Channel

admin.site.register(Channel, ChannelAdmin)





class PostAdmin(admin.ModelAdmin):
    list_display = ['text', 'media', 'send_type', 'created']

    class Meta:
        model = Post


    def get_form(self, request, obj=None, **kwargs):
        form = super(PostAdmin, self).get_form(request, obj, **kwargs)
        try:

            post_id = !!! AND USE IT HERE!!!!

            form.base_fields['channels'].initial = post_id
        except Exception as e:
            print(e)
        return form

您可以将 GET 参数添加到 url。

url = "%s?pid=%s" % (reverse(admin:channels_post_add), obj.id)

然后 request.GET.get("pid")get_form():

class ChannelAdmin(admin.ModelAdmin):

    ...

    def account_actions(self, obj):
        url = "%s?pid=%s" % (reverse(admin:channels_post_add), obj.id)
        return format_html('<a class="button" href="{}">Add post</a>', url)



class PostAdmin(admin.ModelAdmin):

    ...

    def get_form(self, request, obj=None, **kwargs):
        form = super(PostAdmin, self).get_form(request, obj, **kwargs)
        try:
            form.base_fields['channels'].initial = request.GET.get("pid")
        except Exception as e:
            print(e)
        return form

我认为你必须使用 ModelAdmin.get_changeform_initial_data(request)(Django Docs) 来设置初始值。

A hook for the initial data on admin change forms. By default, fields are given initial values from GET parameters. For instance, ?name=initial_value will set the name field’s initial value to be initial_value.

This method should return a dictionary in the form {'fieldname': 'fieldval'}:

url = "%s?channels=%s" % (reverse(admin:channels_post_add), obj.id)

def get_changeform_initial_data(self, request):
    return {'channels': request.GET.get("pid")}