如何在 Django 管理中的字段旁边添加自定义按钮?

Posted

技术标签:

【中文标题】如何在 Django 管理中的字段旁边添加自定义按钮?【英文标题】:How do I add a custom button next to a field in Django admin? 【发布时间】:2013-08-16 06:35:39 【问题描述】:

我有一个客户端模型,其中包含一个客户端 API 密钥字段。

在 Django Admin 中添加新客户端时,我希望在 API 字段旁边有一个按钮来生成新密钥(我有这个方法)。生成后,该字段将使用密钥更新。

如何在字段旁边添加此按钮?我应该使用自定义小部件吗?

【问题讨论】:

从你添加到这个问题的不同标签来看,信息太少,无法认真回答。 您可以覆盖 djangos 管理模板并使用您自己的。这篇文章可能有助于进入正确的方向:code.djangoproject.com/wiki/ExtendingAdminTemplates 【参考方案1】:

在我的例子中,我正在使用我创建的按钮进行 API 调用,所以我也会介绍我是如何做到的。当然你的按钮可以做任何你喜欢的事情。

首先,在您的模型中创建一个将输出您的按钮的函数。我将使用我的示例,即 models.py:

class YourModel(models.Model):

    ....

    def admin_unit_details(self):  # Button for admin to get to API
        return format_html(u'<a href="#" onclick="return false;" class="button" '
                           u'id="id_admin_unit_selected">Unit Details</a>')
    admin_unit_details.allow_tags = True
    admin_unit_details.short_description = "Unit Details"

然后我将该字段添加为只读并将其添加到字段集中,注意您只能在模型管理员上定义字段或字段集。我还添加了媒体来覆盖一些 css,还添加了用于进行 ajax 调用的 js,admin.py:

class YourModelAdmin(admin.ModelAdmin):

    form = YourModelForm
    list_display = ('id', 'agent', 'project', 'completed_date', 'selected_unit', 'is_accepted',
                    'get_lock_for_admin', 'status')

    fields = ('agent', 'project', 'completed_date', 'selected_unit', 'is_accepted',
                    'lock', 'status')

    readonly_fields = ('admin_unit_details', )

    ...

    class Media:
        js = ('admin_custom/js/myjs.js',)  # in static
        css = 'all': ('admin_custom/css/mycss.css', )

我还想指出,我通过表单传递了 API 地址和标头,但您可以在代码中使用正确的标头/密码。我只是把我的全部放在一个地方(settings.py),forms.py(可选):

from settings import API_ADDRESS, API_HEADER
class MyModelForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(WorksheetForm, self).__init__(*args, **kwargs)

        self.fields['selected_unit'].widget = forms.Select(choices=get_worksheet_unit_choice_list(self.instance.id),
                                                           attrs='api_address': API_ADDRESS, 'api_header': API_HEADER)

    ....

最后看一下我的 js,正如我的 admin Media 类所引用的,它位于 admin_custom/js/myjs.js 中:

这类似于添加管理员图像,请参阅here。同样在django doc 中搜索allow_tags 属性,这是一个很好的例子。

// Make sure jQuery (django admin) is available, use admin jQuery instance
if (typeof jQuery === 'undefined') 
    var jQuery = django.jQuery;


var unit_information = ;

jQuery( document ).ready(function() 

    jQuery('#id_admin_unit_selected').click( function() 

        //get the data from id_selected_unit, from the api_header api_address attributes
        var unit_select = jQuery('#id_selected_unit');
        var header = unit_select.attr('api_header');
        var address = unit_select.attr('api_address');
        var selected_unit = unit_select.val();

        if (header && address && selected_unit)
            var unit_address = address + '/units/' + selected_unit
            get_unit(header, unit_address)
        
        else
            // if can't connect to api, so hide
            jQuery('.field-admin_unit_details').hide();
        

    );

);


function get_unit(header, address)

    jQuery.ajax
    (
        type: "GET",
        url: address,
        dataType: 'json',
        headers: 
        "Authorization": header
        ,
        success: function (result) 
            //TODO: output this in a modal & style
            unit_information = JSON.stringify(result);
            alert(unit_information)
        ,
        error: function(xhr, textStatus, errorThrown) 
            alert("Please report this error: "+errorThrown+xhr.status+xhr.responseText);
        
    );


这会在警报中输出,您也可以将其记录到控制台或为其定义自己的模式/样式。

希望这会有所帮助,干杯!

【讨论】:

注意:按钮必须列为只读字段,否则会引发错误。 ***.com/questions/22682516/… 我简化了这个(没有额外的 JS 和 CSS),它对我有用。我将输出按钮的功能移到了管理文件中,以免弄乱我的模型。此外,不再需要allow_tags

以上是关于如何在 Django 管理中的字段旁边添加自定义按钮?的主要内容,如果未能解决你的问题,请参考以下文章

按 django admin 中的自定义列表显示字段进行列表过滤

如何在 django 模型表单中添加自定义字段?

Django:如何在管理表单中的“历史记录”按钮旁边添加一个操作按钮 - 干净利落?

如何在 Django-admin 中添加自定义搜索框?

如何在 Django 会话模型中设置自定义字段?

如何在 Django 管理员中为模型字段使用自定义表单字段?