我正在做一个Django项目,在那里我显示了一个数据列表。当列表太长时,由于显示在该列表中的数据量,页面加载所需的时间更长。
与其使用Django for循环先获取所有数据,然后显示页面,不如先显示页面,然后通过ajax在后台加载数据库中的所有数据。
为了做到这一点,我考虑首先在没有对象数据的情况下显示整个模板,以快速加载页面,然后使用Ajax调用获取带有视图函数的数据,每次一个对象。
这是可行的,我怎样才能做到呢?
我的datalist.py:
from __future__ import absolute_import
from __future__ import print_function
from django.views.generic import ListView
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required, user_passes_test
from django.urls import reverse_lazy , reverse
from django.apps import apps
from django.http import HttpResponse , HttpResponseRedirect , Http404
from .models import *
from .forms import *
from .common import *
from django.http import JsonResponse
import json
from django.forms.models import model_to_dict
from django.core import serializers
from django.core.serializers.json import DjangoJSONEncoder
class DataList(ListView):
@method_decorator(login_required)
def dispatch(self,request, *args, **kwargs):
self.app = ''
self.app1 = self.request.GET.get('app',None)
if self.app1 != None:
self.app = self.app1
else:
self.app = eval(self.kwargs['table'])._meta.app_label
print((self.app))
self.model = apps.get_model(app_label=self.app, model_name=self.kwargs['table'])
self.template_name = "{0}/{1}/list.html".format(self.app,self.kwargs['table'])
request.session['url'] = reverse_lazy('{0}:data-list'.format(self.app), kwargs={'is_list':0,'app':self.app,'table':self.kwargs['table']})
self.name = eval(self.kwargs['table'])._meta.verbose_name_plural
request.session['title_page'] = self.name
return super(DataList, self).dispatch(request,*args, **kwargs)
def get_queryset(self):
if self.kwargs['table'] == 'Myprotocol':
protocoltype = self.request.GET.get('protocoltype')
mytype = self.request.GET.get('type')
queryset = self.model.objects.all()
return queryset
def get_context_data(self, **kwargs):
context = super(DataList, self).get_context_data(**kwargs)
context['page_title'] = self.kwargs['table'] + ' list'
context['app_name'] = self.app
context['table'] = self.kwargs['table']
context['mybase'] = "{0}/base.html".format(self.app)
context['form_name'] = eval('{0}Form'.format(self.kwargs['table']))
context['add_perm'] = self.request.user.has_perm("{0}.add_{1}".format(self.app,self.kwargs['table'].lower()))
context['change_perm'] = self.request.user.has_perm("{0}.change_{1}".format(self.app,self.kwargs['table'].lower()))
context['delete_perm'] = self.request.user.has_perm("{0}.change_{1}".format(self.app,self.kwargs['table'].lower()))
if not self.request.user.is_superuser:
if self.kwargs['table'] == 'Myprotocol':
protocoltype = self.request.GET.get('protocoltype')
context['protocoltype'] = protocoltype
context['myname'] = self.model._meta.verbose_name
context['name'] = self.name
mycreate = str(self.app) + ':data-create'
create_button = reverse_lazy(mycreate, kwargs={'is_list':1,'app':self.app,'table':self.kwargs['table']})
context['create_button'] = create_button
if self.kwargs['table'] == 'Document':
args = {}
args['del_f'] = 0
args['user_id'] = self.request.user.pk
protocol = Protocol.objects.all()
archived = self.model.objects.filter(**args).filter(pk__in=[i.document_id for i in protocol]).order_by('-protocol__protocolid')
context['archived'] = archived
return context我的数据表模板(list.html):
{% if data %}
<table id="myTable1" class="table table-hover">
<thead id="header">
<tr class="mycol__">
<th class="acol1"><a href="#"><i class="fa fa-sync fa-lg"></i> </a></th>
<th class="col2">Field 1 </th>
<th class="col3">Field 2</th>
<th class="col4">Field 3</th>
<th class="col5">Field 4</th>
<th class="col6">Field 5</th>
<th class="col7">Field 6</th>
<th class="col9">Field 7</th>
</tr>
</thead>
<tbody id="tbody">
<!-- HERE IS WHERE THE AJAX SHOULD DISPLAY THE OBJECTS ONE ROW AT A TIME -->
</tbody>
</table>
{% endif %}我的部分表体模板(list_table_body.html):
<tr>
<td class="col2">{{ d.protocolid }}</a></td>
<td class="col4">{{ d.year }}</td>
<td class="col5">{{ d.pcreated }}</td>
<td class="col6">{{ d.subject }}</td>
<td class="col7">{{ d.psender|default_if_none:"< Me >" }}</td>
</tr>编辑17-1-2022:
我首先在list.html中添加了以下内容:
{% if data %}
{% for dataitem in data %}
$.ajax({
headers: {'X-CSRFToken':getCookie('csrftoken')},
url: "{% url 'protocol:myprotocol-item' dataitem.protocol_ptr.id %}",//'/protocol/myprotocol/item/'+dataitem.protocol_ptr+'/',
type: 'get',
dataType: 'json',
success: function(data) {
var tablerows = $('#myTable1 #tbody tr').length;
// alert(tablerows);
if (tablerows === 0){
$("#myTable1 #tbody").append(data.html_form);
}
else if (tablerows > 0){
$("#myTable1 #tbody tr").last().after(data.html_form);
}
// let the tablesorter plugin know that we made a update
// the resort flag set to anything BUT false (no quotes) will trigger an automatic
// table resort using the current sort
var resort = true;
$("table").trigger("update", [resort]);
}, // end of success
error : function(xhr,errmsg,err) {
console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
} // end of error
}); //end of ajax
{% endfor %}
{% endif %}然后,我在views.py中创建了一个python函数,它检查从ajax中提供的id,并使用list_table_body.html作为模板返回json中的特定对象。
它可以工作,但我在想:在加载行时,这意味着它发送了若干个GET调用,等于总对象的数量。这会影响服务器性能吗?
发布于 2022-01-14 21:39:46
你看过jsGrid了吗?它附带了一些钟声和口哨,比如分页等等。我将此解决方案与Django REST框架一起用于实现类似的目标。
https://stackoverflow.com/questions/70716555
复制相似问题