17

我正在使用 AjaxForm 插件来提交我的表单而不刷新。喜欢:

$('#my_form_id').ajaxForm(function(){

        //something on success or fail
    });

这工作正常。当我单击提交按钮时,它会保存表单数据而不刷新。但在此之前;我的模板文件上有 django 消息,例如:

{% for message in messages %}
    <div id="notice" align="center">
        {{ message }}
    </div>
{% endfor %}

如果帖子保存正确或失败,则此代码的作用是显示通知。

现在; 我不能那样做。我不明白如何将这些消息标签与 ajax 函数一起使用。

它只是保存帖子。没有通知。

谢谢你。

编辑 :

add_post 网址:url(r'^admin/post/add/$', view='add_post',name='add_post'),

相关观点:

@login_required(login_url='/login/')
def add_post(request):
    template_name = 'add.html'
    owner = request.user
    if request.method == "POST":
        form = addForm(request.POST)
        if form.is_valid():
            titleform = form.cleaned_data['title']
            bodyform = form.cleaned_data['body']
            checkform = form.cleaned_data['isdraft']

            n = Post(title=titleform, body=bodyform, isdraft=checkform, owner=owner)
            n.save()
            messages.add_message(request, messages.SUCCESS,
                'New post created successfully!')
        else:
            messages.add_message(request, messages.WARNING,
                'Please fill in all fields!')
    else:
        form = addForm()
    return render_to_response(template_name, {'form': form, 'owner': owner,},
        context_instance=RequestContext(request))
4

5 回答 5

15

这些是帮助我解决问题的工具/方法。首先,我有一个名为的辅助实用程序方法render_to_json

# `data` is a python dictionary
def render_to_json(request, data):
    return HttpResponse(
        json.dumps(data, ensure_ascii=False),
        mimetype=request.is_ajax() and "application/json" or "text/html"
    )

我有一个messages.html模板来为弹出消息呈现必要的 html:

{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}

在创建响应 AJAX 请求的消息时,我使用 Djangorender_to_string将消息打包成一个字符串,该字符串存储在data字典中,然后使用 myrender_to_json返回适当的响应:

def my_custom_view(request)
    # ...  your view code
    data = {
        'msg': render_to_string('messages.html', {}, RequestContext(request)),
    }
    return render_to_json(request, data)

然后,在我的 jQuery$.post(...)回调函数中,我检查response对象是否具有msg属性,然后将 的内容插入response.msg到我想要的 DOM 中,如果需要,可以使用 jQuery 转换。我的base.html模板包含<ul>消息的容器:

<ul id="popup-messages-content">
    {% include 'messages.html' %}
</ul>

请注意,以上内容包括messages.html您想要在实际页面加载(非 AJAX 请求)上显示消息的情况 - 如果没有消息,则它是空白的,但<ul>仍然可以将 AJAX 接收到的消息推送到其中。

最后一部分是我在任何$.post(...)回调中使用的 Javascript 函数(需要 jQuery)来显示消息:

function showPopupMessage(content) {
    var elMessages = $('#popup-messages-content');
    if (elMessages.length && content) {
        elMessages.html(content);
    }
}
于 2012-11-06T18:52:11.490 回答
10

您只需像往常一样创建消息,然后在发送响应之前将它们放入字典列表中:

django_messages = []

for message in messages.get_messages(request):
    django_messages.append({
        "level": message.level,
        "message": message.message,
        "extra_tags": message.tags,
})

然后你添加任何数据和你的消息并序列化它,例如:

data = {}
data['success'] = success
data['messages'] = django_messages

return HttpResponse(simplejson.dumps(data), content_type="application/json")

最后在你的ajax:

success: function(data){
                                success = data.success;
                                update_messages(data.messages);
                                if (success){
                                    ...                                                                             
                                }
                            },

和 update_messages 函数:

function update_messages(messages){
$("#div_messages").html("");
$.each(messages, function (i, m) {
                $("#div_messages").append("<div class='alert alert-"+m.level+"''>"+m.message+"</div>");
            });
    

}

它工作得很好,我发现它很容易实现

于 2014-05-22T13:55:41.847 回答
4

这是一个简单的想法。

在 layout.html 中为您的消息添加占位符,这允许在 javascript 中附加新消息:

<div id="messages">
{% for message in messages %}
    <div id="notice" align="center">
        {{ message }}
    </div>
{% endfor %}
</div>

代替:

{% for message in messages %}
    <div id="notice" align="center">
        {{ message }}
    </div>
{% endfor %}

在 add.html 中,添加另一个,例如:

{% if messages %}
<ul class="hidden-messages" style="display:none">
    {% for message in messages %}
        <div id="notice" align="center">
            {{ message }}
        </div>
    {% endfor %}
</ul>
{% endif %}

ajaxForm 看起来像:

$('#your_form_id').ajaxForm({
    success: function(responseText) {
        var newMessages = $(responseText).find('.hidden-messages').html();
        $('#messages').append(newMessages);
    },
});
于 2012-11-06T18:37:41.667 回答
1

在模板中

<div id="ajax_message">
    {% if messages %}
        {% for message in messages %}
            <div class="alert alert-{{ message.tags }}  fade show">
                {{ message|safe }}
            </div>
        {% endfor %}
    {% endif %}
</div>

ajax_send 启动函数后

$("#ajax_message").load("this_url #ajax_message");

或者

function alert_message() {
    var pathname = window.location.pathname;
    $("#ajax_message").load(pathname+" #ajax_message");
}
于 2020-11-08T19:20:09.553 回答
0

使用 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 中的 Network 选项卡和下流量分析器,当一切正常时,您应该会看到一个 POST 请求,然后是一个 GET 请求。

ajax GET 只是获取一个messages.html模板,然后我们用新的消息来填充该模板。我们确保清除第messageDiv一个,这样消息就不会堆积在 gui 上。

于 2021-10-10T09:14:10.373 回答