在我看来你有两个选择:
- 使用Channels,这是一个很棒的 Django Websockets 库:
-
Signals,这是原生 Django 功能,可以让您知道数据何时保存到模型中。
- 那么只需要在javascript端实现Websocket通信即可,比较简单。
signals.py 示例
@receiver(post_save, sender=CanBusAnalyzerJob, dispatch_uid='update_job_status_listeners')
def update_job_status_listeners(sender, instance, **kwargs):
'''
Sends job status to the browser when a Job is modified
'''
job_id = instance.job_id
group_name = 'new-job-' + job_id
message = {
'total': instance.job_total,
'progress': instance.progress,
'status': instance.status
}
channel_layer = channels.layers.get_channel_layer()
async_to_sync(channel_layer.group_send)(
group_name,
{
'type': 'send_job_progress',
'text': message
}
)
JS代码测试websocket连接
<script>
var socket = new WebSocket('ws://' + window.location.host + '/ws/');
socket.onopen = function() {
console.log("Websocket connection done!");
if (socket.readyState == WebSocket.OPEN) {
setInterval(function() {
socket.send('Hello World');
}, 10000);
}
};
socket.onmessage = function(e) {
var data = JSON.parse(e.data);
var message = data['message'];
console.log(data);
};
socket.onclose = function(e) {
console.error('Chat socket closed unexpectedly');
};
</script>
对我来说这是可行的方法,但是如果您想要快速的东西,那么您可以创建一个视图并将其注册到 urls.py 文件中,该文件将每隔 X 秒从您的前端代码调用一次。这将从数据库中获取新数据并已返回 html 代码,或者仅返回数据并在 JS 代码中对其进行处理。
views.py
如果你需要,这个例子也可以接收 POST 参数,like 和 ID(名称在 urls.py 文件中设置)。如果您只需要获取数据删除第三行。
class ToggleFavouriteSignalView(View):
def post(self, request, *args, **kwargs):
obj_id = kwargs['signal_id']
try:
model_obj = CanBusLogAnalyzer.objects.get(id=obj_id)
new_val = False if model_obj.favourite else True
model_obj.favourite = new_val
model_obj.save()
response_text = 'Success:Signal setted as favourite.' if new_val else 'Info:Signal removed as favourite.'
return HttpResponse(response_text, status=200)
except CanBusLogAnalyzer.DoesNotExist:
return HttpResponse('Error:The object no longer exists in the database.', status=503)
except Exception:
return HttpResponse('Error:Please check your internet connection.', status=503)
JS 代码
//For authentication purposes
function getCrsfCookie() {
var cookieValue = null,
name = 'csrftoken';
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
//Runs every 5 seconds
setInterval(function() {
var csrfcookie = getCrsfCookie();
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 503) {
alert("Error when trying to toggle favourite!")
}
};
url_arr = window.location.href.split("/")
base_url = url_arr[0] + "//" + url_arr[2]
var params = 'signal_id=' + signal_id;
xhttp.open('POST', base_url + destination_url, true);
xhttp.setRequestHeader('X-CSRFToken', csrfcookie);
xhttp.send(params);
}, 5000);