【问题标题】:How to refresh chat application built in Django & jQuery?如何刷新用 Django 和 jQuery 构建的聊天应用程序?
【发布时间】:2015-10-06 05:36:34
【问题描述】:

我已经使用 Django 和 jQuery 组合了一个聊天应用程序。但是,我似乎无法在短时间内刷新应用程序,以便发送消息的其他人显示在窗口中。代码如下:

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>

ma​​in.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);
        }
    }
});

【问题讨论】:

    标签: jquery django refresh chat


    【解决方案1】:

    您基本上是在问:如何使用 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 %}
    

    ma​​in.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)。我想你现在就能弄清楚了。

    【讨论】:

    • 您能否澄清一下返回上述部分的 Django 视图是什么意思?我的主视图是查询m = Msgs.objects.all(),然后将其作为上下文{"messages" : m} 传递。我以为我要退回那部分。我的JS很弱。对不起。
    • 你实际上是在返回 return render(request, "alpha/home.html", {'messages': m}) 它使用 'messages' 中提供的数据渲染 alpha/home.html .您可以使用我的答案中的 html 创建一个新模板,然后返回。
    • 知道了。然后在聊天应用上每 3 秒刷新一次整个查询集。
    • js 函数不工作。我也试过 setInterval 。 :-/ 也使用了 console.log(messages),
    • 不会显示在开发控制台上。
  • 终于搞定了function getMessages() { $.get("/messages/", function(messages) { $('#talk').html(messages); var objDiv = document.getElementById("chatMessages"); objDiv.scrollTop = objDiv.scrollHeight; }); } setInterval(function(){ getMessages() }, 3000);
  • 猜你喜欢
    相关资源
    最近更新 更多
    热门标签