Страница администратора Django выполняет javascript на кнопках пользовательских действий
Я пытаюсь добавить пользовательскую кнопку в каждой строке рядом с пользователем на страницу администратора django, что облегчает администратору нажатие на кнопку и создание ссылки сброса пароля для конкретного пользователя, а не переход в скрытый раздел actions
на странице администратора django.
Что-то вроде этого - https://hakibenita.com/how-to-add-custom-action-buttons-to-django-admin
Ниже приведен код, который я реализовал, и он работает и переходит на новую страницу с правильным запросом reset-password
и метод reset_password()
выполняется с отправкой ссылки пользователю.
Однако, когда я нажимаю на кнопку, я хотел бы отправить AJAX GET
запрос на тот же url, что и выше, и просто показать администратору оповещение о завершении запроса вместо перехода на новую страницу. В настоящее время я не могу запустить код javascript, используя метод format_html
в Django (см. код ниже)
class UserAdmin(Admin.modelAdmin):
list_display = ('name', 'email', 'custom_actions')
form = forms.UserAdminForm
def get_urls(self):
urls = super().get_urls()
custom_urls = [
url(
r'reset-password/(?P<user_id>.+)',
self.admin_site.admin_view(self.reset-password),
name='reset-password',
),
]
return custom_urls + urls
def custom_actions(self, obj):
user = user_model.User.get(user_id=obj.id)
password_reset_url = reverse('admin:reset-password', args=[user.id])
return mark_safe(format_html(
f'<a class="button" onclick="parent.location=\'{password_reset_url}\'" >Reset Password</a> '
custom_actions.short_description = 'Custom Actions'
custom_actions.allow_tags = True
def reset_password(self, request, password_reset_id):
password_reset.send_password_reset_link(password_reset_id=password_reset_id)
return HttpResponse(status=200)
Ниже приведен HTML/JS код, который я тестировал для желаемого поведения на странице и он работает, я надеялся вшить то же самое в вышеприведенный Django код, но Django не может выполнить и просто показывает скрипт как строку на странице администратора.
<button id='jax' class="button">AJAX</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("#jax").click(function(){
$.ajax({
type : "GET",
url : "my-dynamic-url",
timeout:10,
jsonp : "jsonp",
success : function (response, textS, xhr) {
console.log('oof')
alert("Password reset link has been resent");
},
error : function (xmlHttpRequest, textStatus, errorThrown) {
if(textStatus==='timeout')
alert("request timed out");
}
});
});
});
</script>
Есть ли правильный способ интегрировать приведенный выше код javascript на страницу администратора по нажатию кнопки?
Не хватает ли запятых? Из примера согласно документации :
format_html("{} <b>{}</b> {}",
mark_safe(some_html),
some_text,
some_other_text,
)
Может быть, вам следует обернуть {password_reset_url}
запятыми и посмотреть, сработает ли это.
Если это не решит вашу проблему, будет полезно рассказать об этом подробнее:
Django не может выполнить скрипт и просто показывает его в виде строки на странице администратора.
Какой скрипт вы имеете в виду?
Решение:
Python:
class UserAdmin(Admin.modelAdmin):
list_display = ('name', 'email', 'custom_actions')
form = forms.UserAdminForm
def get_urls(self):
urls = super().get_urls()
custom_urls = [
url(
r'reset-password/(?P<user_id>.+)',
self.admin_site.admin_view(self.reset-password),
name='reset-password',
),
]
return custom_urls + urls
def custom_actions(self, obj):
user = user_model.User.get(user_id=obj.id)
password_reset_url = reverse('admin:reset-password', args=[user.id])
return mark_safe(format_html(
f'<a class="button" onclick="send_password_link(\'{password_reset_url}\'") >Reset Password</a> '
custom_actions.short_description = 'Custom Actions'
custom_actions.allow_tags = True
def reset_password(self, request, password_reset_id):
password_reset.send_password_reset_link(password_reset_id=password_reset_id)
return HttpResponse(status=200)
HTML:
Это должно быть в разделе base-app/templates/your-app/change_list.html
{% extends "admin/change_list.html" %}
{% load static %}
{% block content %}
<script src="{% static 'js/passwordReset.js' %}"></script>
<!-- Render the rest of the ChangeList view by calling block.super -->
{{ block.super }}
{% endblock %}
Javascript:
Это должно быть в разделе base-app/static/static/js/passwordReset.js
function send_password_link(url) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
alert('Password Reset Sent');
}
};
xhttp.open("GET", url, true);
xhttp.send();
}