自定义 Django 管理站点 - 行内按钮

предположим, у вас есть модель, подобная этой:
在这里插入图片描述

class Foo(models.Model):
    name = models.CharField(max_length=50)
    year = models.IntegerField(max_length=4)
    some_value = models.IntegerField(default=0)


class Bar(models.Model):
    name = models.CharField(max_length=50)
    foo = models.ForeignKey(Foo)

然后,您可以使用 FooAdmin 类在 Django AdminSite 中注册您的模型:

class FooAdmin(admin.ModelAdmin):
    list_display = ['name', 'year', 'some_value']

这很好用,但由于某种原因,您需要在我的管理站点中为每个 Foo 行添加两个按钮。假设我们称它们为 Related_buttonAction_button

您需要这些按钮出现在每一行中并按照以下方式工作:

  • 当用户点击 Related_button 时,将重定向到 Django 管理站点,列出与特定 Foo 对象相关的 Bar
  • 当用户点击 Action_button 时,Foo 类对象的 some_value 字段设置为一个自定义值,比如 15。但在那之前,应该会弹出一个确认窗口(确定吗?y/n)。

如何做到这一点?我发现可以像这样在我的 FooAdmin 中做一些事情:

def button(self, obj):
    return '''<input type="button" value="button" />'''

button.short_description = 'Action'
button.allow_tags = True
list_display = ['name', 'year', 'some_value', 'action']

这将在每一行中显示一个按钮。但是,如何为此按钮设置一个操作?

  1. 解决方案

列表页是一个表单。

<form id="changelist-form" action="" method="post">

向其中添加按钮会提交表单。要使用表单数据,您必须创建一个自定义管理表单。它会很混乱,因为它是一个包含所有显示行的表单集,而不仅仅是您的一行。我想这是可以做到的,但有更好的方法:

大多数情况下,管理操作都可以正常完成。管理操作看起来像这样:

def rename_action(modeladmin, request, queryset):
    queryset.update(name='Ni')

make_published.short_description = "Rename selected objects to 'Ni'"


class FooAdmin(admin.ModelAdmin):
    actions = [rename_action, ...]

但是,如果您希望比管理操作更灵活,请随时为管理编写自定义视图。管理由 Django 本身提供支持,您可以编写可挂接到身份验证系统、检查权限并执行其他所需操作的自定义视图。它像这样:

class Foo(models.Model):
    ...

    def my_action_link(self, obj):
        return '<a href="/admin/app/foo/my_custom_action/%d/" class="link">Action name</a>' %obj.id

    my_action_link.short_description = 'My action'
    my_action_link.allow_tags = True


class FooAdmin(admin.ModelAdmin):
    ...

    list_display = ['name', 'my_action_link', ...]

    def get_urls(self):
        urls = super(FooAdmin, self).get_urls()
        my_urls = patterns('',
            (r'^my_custom_action/(?P<pk>\d+)/$', self.my_view)
        )
        return my_urls + urls

    @permission_required('foo.can_change')
    def my_view(self, request):
        obj = get_object_or_404(Foo, pk=pk)
        obj.do_something()
        # Redirect back to the change list. Or something else?
        # You could add some modelform to this view. :)

我没有测试此代码。但我希望您能理解这个主意。祝您编码愉快!

[编辑]:链接参考 Django 1.6 URL 不再可用。添加了 Django 1.11 URL。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值