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

时间:2013-08-14 10:39:28

标签: django django-forms django-templates django-admin

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

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

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

1 个答案:

答案 0 :(得分:4)

在我的情况下,我正在使用我创建的按钮进行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,还添加了js用于调用ajax的地方,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_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);
        }
    });

}

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

希望这有帮助,干杯!