使用 django-bootstrap5 lib 时如何做到这一点:
向只返回自定义 messages.html 模板的消息视图发出 AJAX 获取请求。
好的,我回顾了迄今为止在这个问题上所做的一些工作,我想出了一个巧妙的解决方案,可能与上面的重复,但是,我的帖子与我专门解决这个问题的帖子不同使用 django-bootstrap5 的编码人员的问题。因此,如果是您,请进一步阅读,这可能会解决您的问题。
这里的<DefaultApp> 是某些 IDE 为 Django 项目创建的默认应用程序。我当前的项目名为AbstractSpacecraft,它还有一个名为AbstractSpacecraft 的子文件夹,其中包含settings.py,我将其称为默认应用程序。
<DjangoProject>/<DefaultApp>/javascript_tools.js:
window.messages_tag_id = "#django-messages-div";
window.messages_url = null;
function load_html_from_url(url, elem) {
$.get(url, function(data, status) {
elem.html(data);
});
}
function display_django_messages() {
messagesDiv = $(window.messages_tag_id);
messagesDiv.empty();
load_html_from_url(window.messages_url, messagesDiv);
}
function post_string_to_url(data, url)
{
$.ajax({
type: 'POST',
url: url,
data: data,
success: function(data, status, xhr) { // Function( Anything data, String textStatus, jqXHR jqXHR )
if ('msg' in data) {
const msg = data['msg'];
console.log(msg);
display_django_messages();
}
},
error : function(xhr, errmsg, err) {
// Provide a bit more info about the error to the console:
if (errmsg) {
console.log('ERROR: ' + errmsg);
display_django_messages();
}
console.log(xhr.status + ": " + xhr.responseText);
}
});
}
function csrf_safe_method(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function setup_ajax_csrf_token(csrf_token) {
// BUGFIX. This took hours to get to work!
// And remember the csrf_token line at the top of template
window.csrf_token = csrf_token;
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrf_safe_method(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrf_token);
}
}
});
}
`
<DjangoProject>/templates/<AppName>/your_template.html(仅相关部分):
<script>
$(document).ready(function()
{
// Remember to call this!
setup_ajax_csrf_token("{{ csrf_token }}");
let ui = window.ui;
$("#diagram-name-form").submit((event) => {
event.preventDefault();
const data = {
"diagram name" : $("#diagram-name-input").val(),
"diagram id" : "{{ diagram_id }}",
};
const set_name_url = "{% url 'set_model_string' Model='Diagram' field='name'%}";
post_string_to_url(data, set_name_url, "{% url 'messages' %}");
});
});
</script>
.....
<div class="form-outline">
<form class="row row-cols-lg-auto g-3 align-items-center" method="post"
id="diagram-name-form">
{% csrf_token %}
<input type="text" id="diagram-name-input" class="form-control" placeholder="Diagram name?" />
</form>
</div>
<DjangoProject>/templates/<DefaultApp>/messages.html:
{% load django_bootstrap5 %}
{% autoescape off %}{% bootstrap_messages %}{% endautoescape %}
<DjangoProject/<DefaultApp>/views.py:
from django.shortcuts import render
from django.views.generic.base import TemplateView, View
class MessagesView(View):
template_name = 'AbstractSpacecraft/messages.html'
def get(self, request, *args, **kwargs):
return render(request, self.template_name)
<DjangoProject>/<DefaultApp>/base.html:
{% block bootstrap5_content %}
{% block as_navbar %} <!-- as = AbstractSpacecraft -->
....
{% endblock %}
<div class="container-fluid">
<div class="row">
<div class="col">
<div class="row" id="django-messages-div">
{% autoescape off %}{% bootstrap_messages %}{% endautoescape %}
</div>
{% block content %}{% endblock %}
</div>
</div>
</div>
{% endblock %}
....
基本上,在我们收到来自 ajax POST 请求的 OK 后,我们会执行 ajax GET 请求,现在一切正常,它可能会工作,但我无法通过查看“网络”选项卡让 messagesDiv.load(url) 工作在 Chrome DevTools 和流量分析器下,当一切正常时,您应该会看到一个 POST 请求,然后是一个 GET 请求。
ajax GET 简单地获取一个messages.html 模板,然后我们用新近知道的消息填充该模板。我们确保首先清除messageDiv,这样消息就不会堆积在 gui 上。