Displaying the data from db in a table, one row/object at a time with Ajax python django

  ajax, django, python-3.x

I am working on a Django project where I display a list of data. When the list is too long the page takes longer to load due to the amount of data that are displayed in that list.

Instead of having a Django for loop to get all the data first and then display the page, I am thinking of first displaying the page and then loading all the data from the database via ajax in the background.

In order to do that I was thinking of first displaying the whole template without the objects’ data to load the page fast and then use an Ajax call to fetch the data with a view function, one object at a time.

Is this viable and how can I do it?

My 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

My Datalist template (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 %}

My partial table body template (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>

Source: Python-3x Questions

LEAVE A COMMENT