因此,我正在加载模型字段中存在的每个值的计数。一切工作正常,但是每次我对数据库进行更改时,我都必须重新启动服务器,以使更改在前端生效。
我认为AJAX可能适合这种情况,但我不知道该怎么做。另外请注意,在查询中我有在模板中使用的注释。
我的看法如下:
def counts(request):
duplicates = Application.objects.all().filter(is_qualified="awarded").values('school_name').annotate(name_count=Count('school_name'))
context = {
'repeated_names' : records,
'duplicates' : duplicates,
'title' : 'Disbursement Details',
}
return render(request, 'calculations/list.html', context)
和我的网址为:
path('list/', default_views.counts, name='count_rows'),
最后是我的模板:
<table class="table table-hover" id="disbursement_table">
<thead class=" wow fadeInLeft">
<tr>
<th>#</th>
<th>School</th>
<th>Number of Applicants</th>
</tr>
</thead>
<tbody class=" wow fadeInRight" wow-data-duration="2s">
{% for application in duplicates %}
<tr class="clickabe-row" data-target="{% url 'dup_detail' application.school_name %}">
<td>{{ forloop.counter}}</td>
<td>{{ application.school_name}}</td>
<td>{{ application.name_count }}</td>
</tr>
{% endfor %}
</tbody>
</table>
有没有一种方法可以使AJAX每次在数据库中发生更改时定期定期更新{{ application.name_count }}
值?
答案 0 :(得分:1)
我认为您有两种选择:
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参数,例如和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);