Django оптимизация xhr запросов
Мужики я долго пытался ускорить то, что я написал не получилось .-. . Обычное Django приложение для работы небольшого предприятия, появилось необходимость создания накладных для сбора товаров. Вкратце есть у нас в модель документа накладной и строчек записей в эту накладную, в другом модуле программы есть модель с каталогом всех товаров, на странице с накладной создается новый объект модели Самой накладной, а потом xhr запросы на сервер генерируют записи в накладной и отрисовывают на странице. Все работает, но медленно .-. На локальной машине 50-100 мс, на yandex-cloud от 180мс до 600мс .-. Подскажите пожалуйста, как еще можно ускорить работу данного кода ? Вот подробные детали моей реализации :
- Models.py для накладных.
from Products.models import Shoe
from mainapp.models import Customer
from django.db.models import Max, Sum
from django.utils.translation import ugettext_lazy as _
class Naclad_sbor(models.Model):
id = models.AutoField(primary_key=True)
def numbers():
no = Naclad_sbor.objects.count()
if no == None:
return 1
else:
return no + 1
number = models.IntegerField(_('Code'),unique=True,default=numbers)
created_at = models.DateTimeField(_('Созданно'),auto_now_add=True,db_index=True,)
customer = models.CharField('Покупатель',max_length=20,blank=True,)
number_tel = models.CharField('Номер телефона',max_length=20,blank=True,null=True,)
Work = 'В работе'
Sobrano = 'Собрано'
Proverka = 'Проверка'
Not_Oplacheno = 'Ожидает оплаты'
Oplacheno = 'Оплаченно'
Transp = 'Ожидает транспортировки'
Chek = 'Проведенна'
TYPE_CHOICES = ((Work, _('В работе')),(Sobrano, _('Собрано')),
(Proverka, _('Проверка')),
(Not_Oplacheno, _('Не Оплаченно')),
(Oplacheno, _('Оплаченно')),
(Transp, _('Ожидает транспортировки')),
(Chek, _('Проведенна')),
)
type = models.CharField(
_('Type'),
max_length=23,
choices=TYPE_CHOICES,
)
@property
def total(self):
return self.items.aggregate(sum=Sum('quantity_package'))['sum']
def TotalPrise(self):
hp = self.items.all()
count = 0
for tp in hp:
gk = tp.total_prise
count = count + gk
return count
class Meta:
ordering = ['-created_at']
class Naclad_sbor_Item(models.Model):
id = models.AutoField(primary_key=True)
document = models.ForeignKey(
Naclad_sbor,
models.CASCADE,
related_name='items',
)
position = models.PositiveIntegerField(
verbose_name=_('Position'),
editable=False,
db_index=True,
)
fason = models.CharField('Фасон', max_length=50, blank=True)
Size = models.CharField('Размеры', max_length=50, blank=True)
Color = models.CharField('Цвет', max_length=20, blank=True)
vedor_code = models.CharField('Артикул', max_length=50)
barcode = models.CharField('Штрихкод', max_length=13)
package = models.IntegerField('Пар в упаковке', blank=True, null=True)
price = models.IntegerField('Цена за штуку', blank=True, null=True,)
note = models.CharField(
max_length=50,
blank=True,
null=True,
)
sborka = models.BooleanField('Сборка', default=False)
proverka = models.BooleanField('Проверка', default=False)
quantity_package = models.IntegerField(
_('Колличество упаковок'),
)
@property
def total_prise(self):
return self.price * self.package * self.quantity_package
@property
def mark(self):
return round(self.price * 1.08)
def save(self, *args, **kwargs):
if not self.position:
position = self.document.items.aggregate(Max('position'))['position__max'] or 0
self.position = position + 1
super(Naclad_sbor_Item, self).save(*args, **kwargs)
class Meta:
ordering = ['position']
- Url:
from . import views
app_name = 'Sbor'
urlpatterns = [
path('', views.sbor, name='sbor'),
path('<int:pk>', views.naclad, name='naclad'),
path('new_naclad', views.new_naclad, name='new_naclad'),
path('end', views.end, name='end'),
path('item/<int:nums>', views.item, name='item'),
path('refresh/<int:nums>', views.refresh_data, name='refresh'),
path('refresh_nac/<int:nums>', views.refresh_data_nac, name='refresh_nac'),
path('add/<int:nums>', views.add, name='add'),
path('obnov_data/<int:nums>', views.obnov_data, name='obnov'),
path('obnov_data_nac/<int:nums>', views.obnov_data_nac, name='obnov_nac')
]
- Views:
from django.shortcuts import render, redirect
from django.http import JsonResponse
from .models import Naclad_sbor, Naclad_sbor_Item
from mainapp.models import Number, Customer
from Products.models import Shoe
@login_required
def new_naclad(request):
Naclad_sbor.objects.create()
tp = Naclad_sbor.objects.latest('created_at').number
naclad_tp = Naclad_sbor.objects.get(number=tp)
nums = str(naclad_tp.number)
return redirect('/sbor/item/' + nums)
@login_required
def item(request, nums):
naclad_tp = Naclad_sbor.objects.get(number=nums)
rab = "Проведенна"
naclads = Naclad_sbor.objects.exclude(type=rab)
shoes = Shoe.objects.only('Color', 'vedor_code', 'Size').all()
customers = Customer.objects.all().select_related('user')
return render(request, 'item.html',
{'shoes': shoes, 'naclad_tp': naclad_tp,
'naclads': naclads, 'customers': customers, })
def add(request, nums):
naclad_tp = Naclad_sbor.objects.get(number=nums)
sbor_item = Naclad_sbor_Item()
sbor_item.notes = request.POST.get('note')
sbor_item.quantity_package = request.POST.get('quantity_package')
sbor_item.document_id = naclad_tp.pk
response = {}
shoe = None
if request.POST.get('shoes'):
shoe = request.POST.get('shoes')
if request.POST.get('barcode'):
shoe = Shoe.objects.get(barcode=request.POST.get('barcode')).pk
botinok = Shoe.objects.get(id=shoe)
sbor_item.fason = botinok.fason
sbor_item.Size = botinok.Size
sbor_item.Color = botinok.Color
sbor_item.vedor_code = botinok.vedor_code
sbor_item.barcode = botinok.barcode
sbor_item.package = botinok.package
sbor_item.price = botinok.Prise.price
try:
tp = Naclad_sbor_Item.objects.get(document_id=naclad_tp.id, barcode=sbor_item.barcode)
quant = int(sbor_item.quantity_package) + tp.quantity_package
tp.quantity_package = quant
tp.save()
except Naclad_sbor_Item.DoesNotExist:
sbor_item.save()
pic = Shoe.objects.only('picture').get(barcode=sbor_item.barcode).picture.url
response['fason'] = sbor_item.fason
response['position'] = sbor_item.position
response['Size'] = sbor_item.Size
response['Color'] = sbor_item.Color
response['pk'] = sbor_item.id
response['pic'] = pic
response['note'] = sbor_item.note
response['shoes'] = sbor_item.vedor_code
response['barcode'] = sbor_item.barcode
response['quantity_package'] = sbor_item.quantity_package
response['package'] = sbor_item.package
response['total_prise'] = ''
response['price'] = sbor_item.price
response['sborka'] = sbor_item.sborka
response['proverka'] = sbor_item.proverka
return JsonResponse(response, content_type='application/json', safe=False)
def refresh_data(request, nums):
# start = datetime.datetime.now()
naclad_tp = Naclad_sbor.objects.get(number=nums)
ti = Naclad_sbor_Item.objects.filter(document=naclad_tp.pk)
response = []
if request.method == 'POST':
for item_storage in ti:
car = item_storage.id
item_storage.fason = request.POST.get('item_fason' + str(car))
item_storage.Size = request.POST.get('item_Size' + str(car))
item_storage.Color = request.POST.get('item_Color' + str(car))
item_storage.vedor_code = request.POST.get('item_shoes' + str(car))
item_storage.package = int(str(request.POST.get('item_package' + str(car))))
item_storage.price = int(request.POST.get('item_price' + str(car)))
item_storage.barcode = request.POST.get('item_barcode' + str(car))
item_storage.quantity_package = int(request.POST.get('item_quantity_package' + str(car)))
item_storage.note = request.POST.get('item_note' + str(car))
if request.POST.get('sborka' + str(car)) == 'true':
item_storage.sborka = True
if request.POST.get('sborka' + str(car)) == 'false':
item_storage.sborka = False
if request.POST.get('proverka' + str(car)) == 'true':
item_storage.proverka = True
if request.POST.get('proverka' + str(car)) == 'false':
item_storage.proverka = False
item_storage.save()
but = request.POST.get('del' + str(car))
try:
pic = Shoe.objects.only('picture').get(barcode=item_storage.barcode).picture.url
except:
pic = ''
response.append(
{
'position': item_storage.position,
'pk': item_storage.pk,
'fason': item_storage.fason,
'Size': item_storage.Size,
'Color': item_storage.Color,
'vedor_code': item_storage.vedor_code,
'package': item_storage.package,
'price': item_storage.price,
'barcode': item_storage.barcode,
'quantity_package': item_storage.quantity_package,
'note': item_storage.note,
'total_pr': item_storage.total_prise,
'del': but,
'proverka': item_storage.proverka,
'sborka': item_storage.sborka,
'pic': pic,
}
)
if but == 'true':
item_storage.delete()
# end = datetime.datetime.now()
# print(f'{end - start}')
return JsonResponse(response, content_type='application/json', safe=False)
def obnov_data(request, nums):
naclad_tp = Naclad_sbor.objects.get(number=nums)
ti = Naclad_sbor_Item.objects.filter(document=naclad_tp.pk)
response = []
if request.method == 'GET':
for i in ti:
try:
pic = Shoe.objects.only('picture').get(barcode=i.barcode).picture.url
except:
pic = ''
response.append(
{
'pk': i.pk,
'fason': i.fason,
'Size': i.Size,
'Color': i.Color,
'vedor_code': i.vedor_code,
'package': i.package,
'price': i.price,
'barcode': i.barcode,
'quantity_package': i.quantity_package,
'note': i.note,
'total_pr': i.total_prise,
'position': i.position,
'proverka': i.proverka,
'sborka': i.sborka,
'pic': pic,
}
)
return JsonResponse(response, content_type='application/json', safe=False)
def refresh_data_nac(request, nums):
naclad_tp = Naclad_sbor.objects.get(number=nums)
response = {}
if request.method == "POST":
naclad_tp.type = request.POST.get('type')
try:
naclad_tp.customer = Customer.objects.get(name=request.POST.get('customer')).name
except Customer.DoesNotExist:
naclad_tp.customer = request.POST.get('customer')
try:
cust = Customer.objects.get(name=request.POST.get('customer'))
naclad_tp.number_tel = Number.objects.get(customer=cust).number
except:
if request.POST.get('number_tel'):
naclad_tp.number_tel = request.POST.get('number_tel')
else:
naclad_tp.number_tel = None
naclad_tp.save()
response['number_tel'] = naclad_tp.number_tel
return JsonResponse(response, content_type='application/json')
def obnov_data_nac(request,nums):
naclad_tp = Naclad_sbor.objects.get(number=nums)
response = {}
if request.method == "GET":
response['type'] = naclad_tp.type
response['customer'] = naclad_tp.customer
response['total'] = naclad_tp.total
response['total_pr'] = naclad_tp.TotalPrise()
response['number_tel'] = naclad_tp.number_tel
return JsonResponse(response, content_type='application/json')
- Js скрипт с вьюшки:
<script type="text/javascript">
document.onload
{
obnov();
obnov();
}
setInterval(async function () {
await obnov()
}, 1000*10);
async function obnov(){
var ref = new XMLHttpRequest();
var urls = "{% url 'Sbor:obnov_nac' naclad_tp.number %}";
ref.open("GET", urls, true);
ref.responseType = 'json';
ref.onreadystatechange = function () {
if (ref.readyState === 4) {
document.getElementById('type').value = ref.response.type;
document.getElementById('customer').value = ref.response.customer;
document.getElementById('total').value = ref.response.total;
document.getElementById('total_pr').value = ref.response.total_pr;
document.getElementById('number_tel').value = ref.response.number_tel
}
};
ref.send();
var xhr = new XMLHttpRequest();
var urlq = "{% url 'Sbor:obnov' naclad_tp.number %}";
xhr.open("GET", urlq, true);
xhr.responseType = 'json';
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
var sh = xhr.response
let bd_item = [];
for (let i in sh){
let el = document.getElementById(`item_box${xhr.response[i].pk}`);
if (!el) {
var lk = document.createElement('tr')
lk.id = `item_box${xhr.response[i].pk}`;
lk.innerHTML =
`<tr><td scope="col" style="width: 7%"><input style="padding: 0; display: inline-block; " aria-label="Позиция" class="form-control" type="text" name="item_pos${xhr.response[i].pk}" maxlength="50" value="${xhr.response[i].position}" disabled></td>
<td scope="col"><input aria-label="Фасон" class="form-control" type="text" id="f${xhr.response[i].pk}" name="item_fason${xhr.response[i].pk}" maxlength="50" value="${xhr.response[i].fason}" onchange="refresh()"></td>
<td scope="col"><input aria-label="Размер" class="form-control" type="text" id="s${xhr.response[i].pk}" name="item_Size${xhr.response[i].pk}" maxlength="50" value="${xhr.response[i].Size}" onchange="refresh()"></td>
<td scope="col"><input aria-label="Цвет" class="form-control" type="text" id="c${xhr.response[i].pk}" name="item_Color${xhr.response[i].pk}" maxlength="50" value="${xhr.response[i].Color}" onchange="refresh()"></td>
<td scope="col"><input aria-label="Заметка" class="form-control" type="text" id="n${xhr.response[i].pk}" name="item_note${xhr.response[i].pk}" maxlength="50" value="${xhr.response[i].note}" onchange="refresh()"></td>
<td scope="col"><input aria-label="Сборка" class="form-control" type="checkbox" name="sborka${xhr.response[i].pk}" id="sborka${xhr.response[i].pk}" onchange="refresh()"></td>
<td scope="col"><input aria-label="Проверка" class="form-control" type="checkbox" name="proverka${xhr.response[i].pk}" id="proverka${xhr.response[i].pk}" onchange="refresh()"></td>
<td scope="col"><input aria-label="Артикул" class="form-control" type="text" id="v${xhr.response[i].pk}" name="item_shoes${xhr.response[i].pk}" maxlength="50" value="${xhr.response[i].vedor_code}" onchange="refresh()"></td>
<td class="jop" scope="col">
<img src="${xhr.response[i].pic}" alt="${xhr.response[i].shoes}" class="im" width="100px" height="90px" style="display: none;"
onerror="this.onerror=null;this.src='http://botinki23.ru/static/images/not-available.png'">
<input aria-label="Штрихкод" class="form-control" type="text" id="b${xhr.response[i].pk}" name="item_barcode${xhr.response[i].pk}" maxlength="50" value="${xhr.response[i].barcode}" onchange="refresh()">
</td>
<td scope="col"><input aria-label="Колличество упаковок" class="form-control" type="number" id="q${xhr.response[i].pk}" name="item_quantity_package${xhr.response[i].pk}" maxlength="50" value="${xhr.response[i].quantity_package}" onchange="refresh()"></td>
<td scope="col"><input aria-label="Колличество пар в упаковке" class="form-control" type="number" id="p${xhr.response[i].pk}" name="item_package${xhr.response[i].pk}" maxlength="50" value="${xhr.response[i].package}" onchange="refresh()"></td>
<td scope="col"><input aria-label="Цена" class="form-control" type="number" id="pr${xhr.response[i].pk}" name="item_price${xhr.response[i].pk}" maxlength="50" value="${xhr.response[i].price}" onchange="refresh()"></td>
<td scope="col"><input aria-label="Сумма" class="form-control" type="number" id="item_total_prise${xhr.response[i].pk}" name="item_total_prise${xhr.response[i].pk}}" maxlength="50" value="${xhr.response[i].total_prise}" onchange="refresh()"></td>
<td scope="col"><input aria-label="Удаление" class="form-control" type="checkbox" id="del${xhr.response[i].pk}" name="del${xhr.response[i].pk}" onchange="refresh()"></td></tr>`;
if(!!xhr.response[i].pk){
document.getElementById('box_item_box').append(lk)
}
}
else {
if (sh.hasOwnProperty(i)) {
document.getElementById(`f${xhr.response[i].pk}`).value = xhr.response[i].fason;
document.getElementById(`s${xhr.response[i].pk}`).value = xhr.response[i].Size;
document.getElementById(`c${xhr.response[i].pk}`).value = xhr.response[i].Color;
document.getElementById(`v${xhr.response [i].pk}`).value = xhr.response[i].vedor_code;
document.getElementById(`p${xhr.response[i].pk}`).value = xhr.response[i].package;
document.getElementById(`pr${xhr.response[i].pk}`).value = xhr.response[i].price;
document.getElementById(`b${xhr.response[i].pk}`).value = xhr.response[i].barcode;
document.getElementById(`q${xhr.response[i].pk}`).value = xhr.response[i].quantity_package;
document.getElementById(`n${xhr.response[i].pk}`).value = xhr.response[i].note;
document.getElementById(`item_total_prise${xhr.response[i].pk}` ).value = xhr.response[i].total_pr;
document.getElementById(`sborka${xhr.response[i].pk}`).checked = xhr.response[i].sborka;
if (xhr.response[i].sborka === true){
document.getElementById(`item_box${xhr.response[i].pk}`).setAttribute("style", "background-color: green;");
}
document.getElementById(`proverka${xhr.response[i].pk}`).checked = xhr.response[i].proverka;
if (xhr.response[i].proverka === true){
document.getElementById(`item_box${xhr.response[i].pk}`).setAttribute("style", "background-color: green;");
}
if (xhr.response[i].sborka === false & xhr.response[i].proverka === false ){
document.getElementById(`item_box${xhr.response[i].pk}`).setAttribute("style", "background-color: transparent;");
}
}
}
bd_item.push(`item_box${xhr.response[i].pk}`);
}
let elem = document.getElementById('box_item_box').children;
let dom_item =[];
for(var g=0, js; g<elem.length;g++){
js = elem.item(g);
dom_item.push(js.id);
}
var c = dom_item.filter(n => bd_item.indexOf(n) === -1);
for (let q of c){
document.getElementById(q).remove();
}
}
};
xhr.send();
$(function () {
$('.jop').hover(function(){
$(this).find('.im').show();
},function(){
$(this).find('.im').hide();
});
})
}
async function refresh_nac(){
let naclads = 'nuc_num=' + {{naclad_tp.number}} + '&' +
'type=' + document.getElementById('type').value + '&' +
'customer=' + document.getElementById('customer').value + '&' +
'number_tel=' + document.getElementById('number_tel').value + '&' +
'csrfmiddlewaretoken={{ csrf_token }}';
let response = await fetch("{% url 'Sbor:refresh_nac' naclad_tp.number %}", {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: naclads
});
}
async function add(){
let addreq = new XMLHttpRequest();
let url = "{% url 'Sbor:add' naclad_tp.number %}";
let data = `shoes=${document.getElementById('id_shoes').value}&quantity_package=${document.getElementById('id_quantity_package').value}&barcode=${document.getElementById('bar').value}¬e=${document.getElementById('id_note').value}&csrfmiddlewaretoken={{ csrf_token }}`;
addreq.open('POST', url, true);
addreq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
addreq.responseType = 'json';
addreq.onreadystatechange = function (){
if (addreq.readyState === 4) {
var tr = document.createElement('tr')
tr.id = 'item_box' + addreq.response.pk;
tr.innerHTML =
`<td><input style="padding: 0; display: inline-block;" aria-label="Позиция" class="form-control" type="text" name="item_pos${addreq.response.pk}" maxlength="50" value="${addreq.response.position}" disabled></td>
<td><input aria-label="Фасон" class="form-control" type="text" id="f${addreq.response.pk}" name="item_fason${addreq.response.pk}" maxlength="50" value="${addreq.response.fason}" onchange="refresh()"></td>
<td><input aria-label="Размер" class="form-control" type="text" id="s${addreq.response.pk}" name="item_Size${addreq.response.pk}" maxlength="50" value="${addreq.response.Size}" onchange="refresh()"></td>
<td><input aria-label="Цвет" class="form-control" type="text" id="c${addreq.response.pk}" name="item_Color${addreq.response.pk}" maxlength="50" value="${addreq.response.Color}" onchange="refresh()"></td>
<td><input aria-label="Заметка" class="form-control" type="text" id="n${addreq.response.pk}" name="item_note${addreq.response.pk}" maxlength="50" value="${addreq.response.note}" onchange="refresh()"></td>
<td><input aria-label="Сборка" class="form-control" type="checkbox" name="sborka${addreq.response.pk}" id="sborka${addreq.response.pk}" onchange="refresh()"></td>
<td><input aria-label="Проверка" class="form-control" type="checkbox" name="proverka${addreq.response.pk}" id="proverka${addreq.response.pk}" onchange="refresh()"></td>
<td><input aria-label="Артикул" class="form-control" type="text" id="v${addreq.response.pk}" name="item_shoes${addreq.response.pk}" maxlength="50" value="${addreq.response.shoes}" onchange="refresh()"></td>
<td class="jop">
<img src="${addreq.response.pic}" alt="${addreq.response.shoes}" class="im" width="100px" height="90px" style="display: none;"
onerror="this.onerror=null;this.src='http://botinki23.ru/static/images/not-available.png'">
<input aria-label="Штрихкод" class="form-control" type="text" id="b${addreq.response.pk}" name="item_barcode${addreq.response.pk}" maxlength="50" value="${addreq.response.barcode}" onchange="refresh()">
</td>
<td><input aria-label="Колличество упаковок" class="form-control" type="number" id="q${addreq.response.pk}" name="item_quantity_package${addreq.response.pk}" maxlength="50" value="${addreq.response.quantity_package}" onchange="refresh()"></td>
<td><input aria-label="Колличество пар в упаковке" class="form-control" type="number" id="p${addreq.response.pk}" name="item_package${addreq.response.pk}" maxlength="50" value="${addreq.response.package}" onchange="refresh()"></td>
<td><input aria-label="Цена" class="form-control" type="number" id="pr${addreq.response.pk}" name="item_price${addreq.response.pk}" maxlength="50" value="${addreq.response.price}" onchange="refresh()"></td>
<td><input aria-label="Сумма" class="form-control" type="number" id="item_total_prise${addreq.response.pk}" name="item_total_prise${addreq.response.pk}}" maxlength="50" value="${addreq.response.total_prise}" onchange="refresh()"></td>
<td><input aria-label="Удаление" class="form-control" type="checkbox" id="del${addreq.response.pk}" name="del${addreq.response.pk}" onchange="refresh()"></td>`;
if(!!addreq.response.pk){
document.getElementById('box_item_box').append(tr)
}
document.getElementById('bar').value = '';
document.getElementById('id_shoes').value = '';
document.getElementById('bar').focus();
}
};
addreq.send(data);
}
async function refresh(){
let lol = new XMLHttpRequest();
let urlq = "{% url 'Sbor:obnov' naclad_tp.number %}";
let xhr = new XMLHttpRequest();
let urlg = "{% url 'Sbor:refresh' naclad_tp.number %}";
let shoe = '';
lol.open("GET", urlq, true);
lol.responseType = 'json';
lol.onreadystatechange = function () {
if (lol.readyState === 4) {
var sh = lol.response
for (let i in sh){
shoe = shoe +
'item_fason' + lol.response[i].pk + '=' + document.getElementById('f' + lol.response[i].pk).value + '&' +
'item_Size' + lol.response[i].pk + '=' + document.getElementById('s' + lol.response[i].pk).value + '&' +
'item_Color' + lol.response[i].pk + '=' + document.getElementById('c' + lol.response[i].pk).value + '&' +
'item_shoes' + lol.response[i].pk + '=' + document.getElementById('v' + lol.response[i].pk).value + '&' +
'item_package' + lol.response[i].pk + '=' + document.getElementById('p' + lol.response[i].pk).value + '&' +
'item_price' + lol.response[i].pk + '=' + document.getElementById('pr' + lol.response[i].pk).value + '&' +
'item_barcode' + lol.response[i].pk + '=' + document.getElementById('b' + lol.response[i].pk).value + '&' +
'item_quantity_package' + lol.response[i].pk + '=' + document.getElementById('q' + lol.response[i].pk).value + '&' +
'item_note' + lol.response[i].pk + '=' + document.getElementById('n' + lol.response[i].pk).value + '&' +
'del' + lol.response[i].pk + '=' + document.getElementById('del' + lol.response[i].pk).checked + '&' +
'proverka' + lol.response[i].pk + '=' + document.getElementById('proverka' + lol.response[i].pk).checked + '&' +
'sborka' + lol.response[i].pk + '=' + document.getElementById('sborka' + lol.response[i].pk).checked + '&';
}
shoe = shoe + 'csrfmiddlewaretoken={{ csrf_token }}';
xhr.open("POST", urlg, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.responseType = 'json';
xhr.onreadystatechange = function () {
if (lol.readyState === 4) {
let sh = xhr.response;
for (let i in sh){
if(xhr.response[i].del === 'true'){
document.getElementById('item_box'+ xhr.response[i].pk).remove()
}
document.getElementById(`sborka${xhr.response[i].pk}`).checked = xhr.response[i].sborka;
if (xhr.response[i].sborka === true){
document.getElementById(`item_box${xhr.response[i].pk}`).setAttribute("style", "background-color: green;");}document.getElementById(`proverka${xhr.response[i].pk}`).checked = xhr.response[i].proverka;
if (xhr.response[i].proverka === true){ document.getElementById(`item_box${xhr.response[i].pk}`).setAttribute("style", "background-color: green;");
}
if (xhr.response[i].sborka === false & xhr.response[i].proverka === false ){
document.getElementById(`item_box${xhr.response[i].pk}`).setAttribute("style", "background-color: transparent;");
}
}
}
}
xhr.send(shoe)
}
};
lol.send();
}
</script>
{% endblock %}
Думаю вьюшки самого редактирования накладной хватит.