【发布时间】:2020-07-14 10:20:47
【问题描述】:
我在渲染 HTML 元素“实时”时遇到问题。
这是我的想法,我有一个顶栏,它包含在“base.html”中(不扩展任何内容),如下所示:
...
base.html
<div id="content-wrapper" class="d-flex flex-column">
<!-- Main Content -->
<div id="content">
<!-- Top Bar -->
{% include 'topbar.html' %}
...
这就是“topbar.html”本身:
topbar.html
<!-- Topbar -->
{% load static %}
{% load custom_tags %}
{% notification_tag as notifications %}
{% current_time as current_time %}
{% events as all_events %}
...
<ul class="navbar-nav ml-auto">
<!-- Nav Item - Alerts -->
<li class="nav-item dropdown no-arrow mx-1">
<a class="nav-link dropdown-toggle" href="#" id="alertsDropdown" role="button"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-bell fa-fw"></i>
<!-- Counter - Alerts -->
{% if notifications %}
{% for notif in notifications %}
{% if notif.date_to_remind <= current_time %}
<span class="badge badge-danger badge-counter">{{ notifications.count }}</span>
{% endif %}
{% endfor %}
{% endif %}
</a>
<!-- Dropdown - Alerts -->
<div class="dropdown-list dropdown-menu dropdown-menu-right shadow animated--grow-in"
aria-labelledby="alertsDropdown">
<h6 class="dropdown-header">
Obaveštenja
</h6>
{% for n in notifications %}
{% if not n.viewed %}
<a class="dropdown-item d-flex align-items-center" href="{% url 'notification' n.pk %}">
<div class="mr-3">
<div class="icon-circle bg-primary">
<i class="fas fa-file-alt text-white"></i>
</div>
</div>
<div>
<div class="small text-gray-500">{{ n.eluid_posla }}</div>
<span class="font-weight-bold">{{ n.message|slice:"25" }}</span>
</div>
</a>
{% endif %}
{% endfor %}
<a class="dropdown-item text-center small text-gray-500"
href="{% url 'notifications_all' %}">Prikaži
sva obaveštenja</a>
</div>
</li>
...
这个想法是,当在确切时间有通知时,通知警报会显示(来自 span 元素的简单红点) - 但不会刷新页面。我设法显示通知警报,但仅在手动刷新之后,因此显示通知和内容的逻辑很好。我只需要一些帮助来编写 Ajax 调用。
我正在从自定义模板标签中提取数据,因此没有网址:
custom_tags.py
@register.simple_tag(name='notification_tag')
def all_notifications():
current = timezone.now() + timezone.timedelta(hours=settings.ADD_HOURS)
notification = Notifications.objects.all().filter(viewed=False, date_to_remind__lte=current)
return notification
@register.simple_tag(name='events')
def all_events():
events = Events.objects.all()
return events
@register.simple_tag(name='current_time')
def now():
current = timezone.now() + timezone.timedelta(hours=settings.ADD_HOURS)
return current
我应该如何处理这个问题?我应该把 Ajax 代码块放在哪里?我应该在 custom_tags.py 还是视图中编写 Ajax 请求?
我也会复制我的views.py,但这些函数不会直接呈现在顶部栏中。我正在使用另一个模板的视图,它工作正常,并且不需要在那里使用 Ajax。
views.py
@method_decorator(login_required, name='dispatch')
class AllNotifications(ListView):
model = Notifications
template_name = 'notifications/all.html'
context_object_name = 'notificaion_list'
paginate_by = 5
def get_context_data(self, **kwargs):
context = super(AllNotifications, self).get_context_data(**kwargs)
notifications = self.get_queryset().order_by('date_to_remind')
page = self.request.GET.get('page')
paginator = Paginator(notifications, self.paginate_by)
try:
notifications = paginator.page(page)
except PageNotAnInteger:
notifications = paginator.page(1)
except EmptyPage:
notifications = paginator.page(paginator.num_pages)
context['notification_list'] = notifications
return context
def post(self, request):
if request.is_ajax():
data = {'notifs': self.get_queryset()}
return JsonResponse(data)
@method_decorator(login_required, name='dispatch')
class Notification(DetailView):
model = Notifications
template_name = 'notifications/notification_details.html'
context_object_name = 'notification_details'
def get_context_data(self, **kwargs):
context = super(Notification, self).get_context_data(**kwargs)
self.object.viewed = True
self.object.save()
return context
@method_decorator(login_required, name='dispatch')
class NotificationCreate(CreateView):
model = Notifications
@method_decorator(login_required, name='dispatch')
class NotificationDelete(DeleteView):
model = Notifications
def get_success_url(self):
return reverse('notifications_all')
这是我的 base.html:
base.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=yes">
<meta name="description" content="">
<meta name="author" content="dev.Ink">
<link rel="shortcut icon" type="image/png" href="{% static 'login/favicon.ico' %}"/>
<!----------------------------------------------------------------------------------------------------------------->
<title>Teledirekt | {% block title %}{% endblock title %}</title>
<!----------------------------------------------------------------------------------------------------------------->
<!-- Custom fonts for this template-->
<link href="{% static 'dash/vendor/fontawesome-free/css/all.min.css' %}" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i"
rel="stylesheet">
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.css">
<!-- Page level plugin CSS-->
<link rel="stylesheet" href="{% static 'dash/vendor/datatables/dataTables.bootstrap4.css' %}">
<link rel="stylesheet" href="{% static 'basic/css/style.css' %}">
<!-- Custom styles for this template-->
<link rel="stylesheet" href="{% static 'dash/css/sb-admin-2.css' %}">
<link rel="stylesheet" href="{% static 'base.css' %}">
{# Include Bootstrap 4 and jQuery #}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
crossorigin="anonymous">
<style>
html, body {
margin: 0;
padding: 0;
height: 100%;
overflow: paged-x;
overflow-x: scroll;
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
}
</style>
</head>
<!--------------------------------------------------------------------------------------------------------------------->
<body id="page-top">
<!-- Page Wrapper -->
<div id="wrapper">
<!-- Side bar -->
{% include 'sidebar.html' %}
<!-- Content Wrapper -->
<div id="content-wrapper" class="d-flex flex-column">
<!-- Main Content -->
<div id="content">
<!-- Top Bar -->
{% include 'topbar.html' %}
<!-- Begin Page Content -->
<div class="container-fluid -align-center">
<!-- Content Row -->
<div class="row">
{% block content_row %}
{% endblock content_row %}
</div>
</div>
</div>
<!-- Footer -->
{% include 'footer.html' %}
<!-- End of Main Content -->
</div>
</div>
<!-- Logout Modal-->
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Da li želite da izađete?</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">Klikom na "Izlaz" prekidate Vašu sesiju.</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Povratak</button>
<a class="nav-link" href="javascript:{document.getElementById('logout').submit()}" onclick="">Izlaz</a>
<form action="{% url 'user:logout' %}" id="logout" method="POST">
{% csrf_token %}
<input type="hidden">
</form>
</div>
</div>
</div>
</div>
<!-------------------------------------------------------------------------------------------------------------------->
<!-- Bootstrap core JavaScript-->
<script src="{% static 'dash/vendor/jquery/jqueryfull.js' %}"></script>
<script src="{% static 'dash/vendor/bootstrap/js/bootstrap.bundle.min.js' %}"></script>
<!-- Core plugin JavaScript-->
<script src="{% static 'dash/vendor/jquery-easing/jquery.easing.min.js' %}"></script>
<!-- Page level plugin JavaScript-->
<script src="{% static 'dash/vendor/chart.js/Chart.min.js' %}"></script>
<script src="{% static 'dash/vendor/datatables/jquery.dataTables.js' %}"></script>
<script src="{% static 'dash/vendor/datatables/dataTables.bootstrap4.js' %}"></script>
<!-- Custom scripts for all pages-->
<script src="{% static 'dash/js/sb-admin-2.min.js' %}"></script>
<script src="{% static 'opportunity/opp.js' %}"></script>
<!-- Demo scripts for this page-->
<script src="{% static 'dash/js/demo/datatables-demo.js' %}"></script>
<script src="{% static 'dash/js/demo/chart-area-demo.js' %}"></script>
</body>
</html>
所以再一次,我只需要在通知时间达到当前时间时出现 span 元素的“徽章危险”,无需手动刷新。
【问题讨论】:
-
我担心你需要socket.io。或者您需要每 1 分钟向服务器发出一次
ajax请求,并检查通知时间是否达到当前时间。 -
知道如何发出 Ajax 请求,因为这不是标准方法?由于我的函数不在views.py中,我该怎么做呢?
-
您需要每分钟从
topbar.html文件向服务器发出一个ajax 请求。如果你真的想要,如果我有时间我会回答的 -
其实那太好了!
-
你能把文件
base.html贴出来,以便我为你的网站提供一个例子。
标签: jquery django ajax django-views django-templates