如何刷新 Django 和 jQuery 中内置的聊天应用程序?

How to refresh chat application built in Django & jQuery?

我使用 Django 和 jQuery 构建了一个聊天应用程序。但是,我似乎无法在短时间间隔后刷新应用程序,以便发送消息的其他人显示在 window 中。这是代码:

urls.py

urlpatterns = [
    url(r'^home/$', views.home),
    url(r'^post/$', views.post),
]

views.py

def home(request):
    m = Msgs.objects.all()
    return render(request, "alpha/home.html", {'messages': m})

def post(request):
    if request.method == "POST":
        msg = request.POST.get('msg')
        if msg != '':
            m = Msgs(msg=msg, usr=request.user)
            m.save()
            return JsonResponse({"msg" : m.msg, "user" : m.usr.username})
    else:
        return JsonResponse({"nothing to see" : "this isn't happening"})

home.html

<div class="chatContainer">
    <div class="chatHeader">
        <h3>Welcome {{ request.user }}</h3>
    </div>
    <div id="chatMessages" class="chatMessages">
        <ul id="talk">

            {% for obj in messages %}
                {% if obj.usr == request.user %}
                    <li class=cm>{{ obj.msg }}</li>
                {% else %}
                    <li class=cm-other>{{ obj.msg }}</li>
                {% endif %}
            {% empty %}
                <li class="cm">No previous messages to display.</li>
            {% endfor %}
        <script>
            var objDiv = document.getElementById("chatMessages");
            objDiv.scrollTop = objDiv.scrollHeight;
        </script>
        </ul>
    </div>
    <div class="chatBottom">
        <form method="post" action="/post/" id="chatForm">
            <input type="text" name="msg" id="msg" placeholder="Write something..." />
            <input type="submit" id="submit" value="Post" />
        </form>
    </div>

main.js

$('#chatForm').on('submit', function(event) {
    event.preventDefault();
    console.log("form submitted!");
    create_post();
});

function create_post() {
    console.log("create post is working!")

    $.ajax({
        url : "/post/",
        type : "POST",
        data : { msg : $('#msg').val() },

        success : function(json) {
            $('#msg').val('');
            console.log(json);
            $('#talk').append("<li class=cm>" + json.msg + "</li>");
            var objDiv = document.getElementById("chatMessages");
            objDiv.scrollTop = objDiv.scrollHeight;
            console.log("success");
        },
    });
};

// This function enables/disables the post button
$(document).ready(function() {
     $('#submit').attr('disabled','disabled');
     $('#msg').keyup(function() {
        if($(this).val() != '') {
           $('#submit').removeAttr('disabled');
        }
        else {
        $('#submit').attr('disabled','disabled');
        }
     });
 });


// This function gets cookie with a given name
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');

/*
The functions below will create a header with csrftoken
*/

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function sameOrigin(url) {
    // test that a given url is a same-origin URL
    // url could be relative or scheme relative or absolute
    var host = document.location.host; // host + port
    var protocol = document.location.protocol;
    var sr_origin = '//' + host;
    var origin = protocol + sr_origin;
    // Allow absolute or scheme relative URLs to same origin
    return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
        (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
        // or any other URL that isn't scheme relative or absolute i.e relative.
        !(/^(\/\/|http:|https:).*/.test(url));
}

$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
            // Send the token to same-origin, relative URLs only.
            // Send the token only if the method warrants CSRF protection
            // Using the CSRFToken value acquired earlier
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

您基本上是在问:如何与 javascript 和 Django 建立聊天。

最简单的方法是使用 javascript 的简单 GET 请求仅检索消息,并且每 3 秒左右执行一次。查找 javascript setTimeout() 方法。

view.py

# add this method
def messages(request):
    m = Msgs.objects.all()
    return render(request, "alpha/messages.html", {'messages': m})

messages.html

        {% for obj in messages %}
            {% if obj.usr == request.user %}
                <li class=cm>{{ obj.msg }}</li>
            {% else %}
                <li class=cm-other>{{ obj.msg }}</li>
            {% endif %}
        {% empty %}
            <li class="cm">No previous messages to display.</li>
        {% endfor %}

main.js

function getMessages() {
    $.get("/messages/", function(messages) {
        $("#talk").html(messages);
    });
    // repeat this method after 3 seconds
    setTimeout(getMessages, 3000);
}

然后,使用 javascript,用新检索的消息覆盖当前消息。

这是最简单的方法。您可能会注意到这是非常多余的,因为您也可以只检索新消息。这通常是通过使用 'last_message_id' 参数执行 GET 请求来完成的,然后您只需执行类似

的查询
Msgs.objects.all().filter(id > last_message_id)

有很多关于这个主题的教程(不仅仅是特定的 django)。我想你现在就能弄明白了。