In my case I am making an API call with a button I create so I'll throw in how I did that too. Ofcourse your button can do whatever you like.
First, in your model create a function that will output your button. I will use my example, i.e. 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"
I then added the field as readonly and added it to the fieldsets, note you can only have either fields or fieldsets defined on the model admin. I aslo added media to overwrite some css and also added the js for where the ajax call will be made, 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', )}
I also wanted to note that I passed the API address and header through the Form, but you can use the right header/password in the code. I just keep mine all in one place (settings.py), forms.py (optional):
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})
....
Lastly here is a look at my js, as referenced by my admin Media class, it is in admin_custom/js/myjs.js:
This is similar to adding an admin image, see here. Also search for allow_tags attribute in this django doc, it shows a good example.
// 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);
}
});
}
This outputs it in an alert, you can also log it to the console or define your own modal / style for it.
Hope this helps, Cheers!