def clean_start_date(self): """Проверят на пустоту введенные данные. """ if not self.cleaned_data.get('start_date', ''): raise ValidationError(_('Required field.')) start_date = self.cleaned_data.get('start_date', '').strip() start_date = start_date.split(r'/') conf = SevercartConfigs() if len(start_date) == 3: # если пользователь не смухлевал, то кол-во элементов = 3 date_value = start_date[0] month_value = start_date[1] year_value = start_date[2] date_value = str2int(date_value) month_value = str2int(month_value) year_value = str2int(year_value) gte_date = datetime.datetime(year=year_value, month=month_value, day=date_value, hour=0, minute=0, microsecond=0, tzinfo=pytz.timezone(conf.time_zone) ) else: raise ValidationError(_('Error in start date.')) return gte_date
def clean_end_date(self): """Проверят на пустоту введенные данные. """ # проверяем на корректность дату окончания просмотра списка end_date = self.cleaned_data.get('end_date', '').strip() end_date = end_date.split(r'/') conf = SevercartConfigs() if end_date and len(end_date) == 3: # если пользователь не смухлевал, то кол-во элементов = 3 date_value = end_date[0] #date_value = del_leding_zero(date_value) month_value = end_date[1] #month_value = del_leding_zero(month_value) year_value = end_date[2] #lte_date = '%s-%s-%s 23:59:59' % (year_value, month_value, date_value,) date_value = str2int(date_value) month_value = str2int(month_value) year_value = str2int(year_value) lte_date = datetime.datetime(year=year_value, month=month_value, day=date_value, hour=23, minute=59, microsecond=999, tzinfo=pytz.timezone(conf.time_zone) ) else: return False return lte_date
def settings_mail(request): """Форма настройки почтового ящика, с которого будут приходить уведомления """ context = dict() context['sender_form'] = SendTestMail() conf = SevercartConfigs() context['settings_form'] = SMTPsettings( initial={ 'smtp_server': conf.smtp_server, 'smtp_port': conf.smtp_port, 'email_sender': conf.email_sender, 'smtp_login': conf.smtp_login, 'smtp_password': conf.smtp_password, 'use_ssl': conf.use_ssl, 'use_tls': conf.use_tls, }) return render(request, 'service/settings_mail.html', context)
def general_settings(request): """Вывод формы настройки отрисовки наклеек. """ context = {} conf = SevercartConfigs() if request.method == 'POST': form = StickFormat(request.POST) if form.is_valid(): data_in_post = form.cleaned_data choice = data_in_post.get('choice', 'A4') print_qr_code = data_in_post.get('print_qr_code') time_zone = data_in_post.get('time_zone') show_time = data_in_post.get('show_time') conf.page_format = choice conf.print_bar_code = print_qr_code conf.time_zone = time_zone conf.show_time = show_time conf.commit() context['form'] = form messages.success(request, _('Settings success saved.')) else: context['form'] = form else: print_qr_code = 1 if conf.print_bar_code else 2 show_time = 1 if conf.show_time else 2 form = StickFormat( initial={ 'choice': conf.page_format, 'print_qr_code': print_qr_code, # Внимание! Есть соблазнзаменить на self.print_qr_code 'time_zone': conf.time_zone, 'show_time': show_time, }) context['form'] = form return render(request, 'service/general_settings.html', context)
def process_request(self, request): # lang_code принимает значения либо ru, либо en lang_code = request.session.get('lang_code', 0) if lang_code: translation.activate(lang_code) request.LANGUAGE_CODE = translation.get_language() # иначе оставляем всё как есть request.HOME_SITE = settings.HOME_SITE request.VERSION = settings.VERSION request.YEAR = datetime.date.today().year # оиспользуется для обновления браузерного кэша статических # файлов при выпуске нового релиза request.CACHEVERSION = settings.VERSION.replace('.', '') # длина номера РМ после которого будет производиться усечение request.TRLEN = settings.TRLEN # отключаем показ копирайтов request.SHOW_COPYRIGHT = settings.SHOW_COPYRIGHT conf = SevercartConfigs() request.TZ = conf.time_zone request.SHOW_TIME = conf.show_time request.SHOW_HELP = settings.SHOW_HELP
def ajax_report_stale(request): """Отчёт по залежавшимся РМ. """ context = dict() form = NoUse(request.POST) if form.is_valid(): data_in_post = form.cleaned_data org = data_in_post.get('org', '') diap = data_in_post.get('diap', '') if (diap == 10) or (diap == 20): old_cart = CartridgeItem.objects.filter(departament=org) result = old_cart.order_by('cart_date_change')[:diap] elif diap == 0: conf = SevercartConfigs() cur_date = timezone.now() old_cart = CartridgeItem.objects.filter(departament=org) last_year = datetime.datetime(year=cur_date.year - 1, month=cur_date.month, day=cur_date.day, hour=0, minute=0, second=0, microsecond=0, tzinfo=pytz.timezone(conf.time_zone)) result = old_cart.filter( cart_date_change__lte=last_year).order_by('cart_date_change') else: pass else: context['error'] = '3' context['text'] = form.errors.as_json() return JsonResponse(context) # показываем форму, если произошли ошибки # context['form'] = form csv_full_name, csv_file_name = rotator_files(request, file_type='csv') encoding = 'cp1251' with open(csv_full_name, 'w', newline='', encoding=encoding) as csvfile: fieldnames = ['number', 'name', 'date', 'amount', 'status'] writer = csv.DictWriter(csvfile, fieldnames, delimiter=';') writer.writerow({ 'number': '', 'name': '', 'date': '', 'amount': '', 'status': '' }) writer.writerow({ 'number': '', 'name': '', 'date': '', 'amount': '', 'status': '' }) writer.writerow({ 'number': '', 'name': '', 'date': '', 'amount': '', 'status': '' }) writer.writerow({ 'number': '', 'name': '', 'date': '', 'amount': '', 'status': '' }) writer.writerow({ 'number': '', 'name': '', 'date': '', 'amount': '', 'status': '' }) writer.writerow({ 'number': _('Number'), 'name': _('Name'), 'date': _('Date of last cases'), 'amount': _('Number refills'), 'status': _('Status') }) for item in result: writer.writerow({ 'number': item.cart_number, 'name': item.cart_itm_name, 'date': formats.date_format(item.cart_date_change, 'd.m.Y'), 'amount': item.cart_number_refills, 'status': pretty_status(item.cart_status) }) context['text'] = render_to_string('reports/report_stale_ajax.html', context={'result': result}) context['url'] = settings.STATIC_URL + 'csv/' + csv_file_name context['error'] = '0' return JsonResponse(context)
def ajax_reports_brands(request): """Отчёт по потреблённым наименованиям """ from common.helpers import del_leding_zero import operator context = dict() form = UseProducts(request.POST) if form.is_valid(): data_in_post = form.cleaned_data start_date = data_in_post.get('start_date') end_date = data_in_post.get('end_date') org = data_in_post.get('org') unit = data_in_post.get('unit') else: context['error'] = '3' context['text'] = form.errors.as_json() return JsonResponse(context) if unit: child = unit root_ou = False #family = root_ou.get_descendants(include_self=True) else: root_ou = org root_ou = root_ou.pk child = False #family = root_ou.get_descendants(include_self=False) result = list() conf = SevercartConfigs() time_offset = datetime.datetime.now(pytz.timezone( conf.time_zone)).strftime('%z') start_date = start_date + time_offset if end_date: end_date = end_date + time_offset if child and start_date and not (end_date): # если определена дата начала анализа, дата окончания пропущена SQL_QUERY = """SELECT cart_type, COUNT(cart_type) as cart_count FROM events_events WHERE event_type = 'TR' AND event_org = '%s' AND date_time >= '%s' GROUP BY cart_type ORDER BY cart_count DESC; """ % ( child, start_date, ) if child and not (start_date) and end_date: # если проеделена крайняя дата просмотра, а дата начала # не определена SQL_QUERY = """SELECT cart_type, COUNT(cart_type) as cart_count FROM events_events WHERE event_type = 'TR' AND event_org = '%s' AND date_time <= '%s' GROUP BY cart_type ORDER BY cart_count DESC; """ % ( child, end_date, ) if child and start_date and end_date: SQL_QUERY = """SELECT cart_type, COUNT(cart_type) as cart_count FROM events_events WHERE event_type = 'TR' AND event_org = '%s' AND date_time >= '%s' AND date_time <= '%s' GROUP BY cart_type ORDER BY cart_count DESC; """ % ( child, start_date, end_date, ) # ветка для SQL запросов если выбран депртамент, а орг. подразделение нет if root_ou and start_date and not (end_date): # если определена дата начала анализа, дата окончания пропущена SQL_QUERY = """SELECT cart_type, COUNT(cart_type) as cart_count FROM events_events WHERE event_type = 'TR' AND departament = %s AND date_time >= '%s' GROUP BY cart_type ORDER BY cart_count DESC; """ % ( root_ou, start_date, ) if root_ou and not (start_date) and end_date: # если проеделена крайняя дата просмотра, а дата начала # не определена SQL_QUERY = """SELECT cart_type, COUNT(cart_type) as cart_count FROM events_events WHERE event_type = 'TR' AND departament = %s AND date_time <= '%s' GROUP BY cart_type ORDER BY cart_count DESC; """ % ( root_ou, end_date, ) if root_ou and start_date and end_date: SQL_QUERY = """SELECT cart_type, COUNT(cart_type) as cart_count FROM events_events WHERE event_type = 'TR' AND departament = %s AND date_time >= '%s' AND date_time <= '%s' GROUP BY cart_type ORDER BY cart_count DESC; """ % ( root_ou, start_date, end_date, ) ##### cursor = connection.cursor() cursor.execute(SQL_QUERY) result = cursor.fetchall() # сохраняем результаты работы скрипта в csv файле csv_full_name, csv_file_name = rotator_files(request, file_type='csv') encoding = 'cp1251' with open(csv_full_name, 'w', newline='', encoding=encoding) as csvfile: fieldnames = ['name', 'amount'] writer = csv.DictWriter(csvfile, fieldnames, delimiter=';') writer.writerow({'name': '', 'amount': ''}) writer.writerow({'name': '', 'amount': ''}) writer.writerow({'name': '', 'amount': ''}) writer.writerow({'name': _('Start range'), 'amount': start_date}) writer.writerow({'name': _('End range'), 'amount': end_date}) writer.writerow({'name': '', 'amount': ''}) writer.writerow({'name': '', 'amount': ''}) writer.writerow({'name': _('Name'), 'amount': _('Items count')}) for item in result: writer.writerow({'name': item[0], 'amount': item[1]}) context['text'] = render_to_string('reports/brands_ajax.html', context={'result': result}) context['url'] = settings.STATIC_URL + 'csv/' + csv_file_name context['error'] = '0' return JsonResponse(context)
def settings_email(request): """ """ resp_dict = dict() form = SMTPsettings(request.POST) if form.is_valid(): data_in_post = form.cleaned_data mconf = SevercartConfigs() mconf.smtp_server = data_in_post['smtp_server'] mconf.smtp_port = data_in_post['smtp_port'] mconf.email_sender = data_in_post['email_sender'] mconf.smtp_login = data_in_post['smtp_login'] mconf.smtp_password = data_in_post['smtp_password'] mconf.use_ssl = data_in_post['use_ssl'] mconf.use_tls = data_in_post['use_tls'] mconf.commit() resp_dict['errors'] = '' resp_dict['text'] = _('Settings successfully saved.') else: error_message = dict([(key, [error for error in value]) for key, value in form.errors.items()]) resp_dict['errors'] = error_message return JsonResponse(resp_dict)
def events_decoder(qso, time_zone_offset=0, simple=True): """Функция докодер симолических мнемоник в человекочитаемый формат. Единственный обязательный аргумент на входе - список объектов QuerySet """ frdly_es = [] conf = SevercartConfigs() current_tz = pytz.timezone(conf.time_zone) for entry in qso: if entry.event_type == 'AD': entry_obj = {} data_env = entry.date_time if simple: text_com = _('Added user %(user_name)s.') % { 'user_name': entry.event_user } else: text_com = _( '№ %(cart_number)s (%(cart_type)s) added user %(user_name)s.' ) % { 'cart_number': entry.cart_number, 'cart_type': entry.cart_type, 'user_name': entry.event_user } #entry_obj['data_env'] = data_env + timedelta(hours=time_zone_offset) entry_obj['data_env'] = do_timezone(data_env, conf.time_zone) entry_obj['text_com'] = text_com frdly_es.append(entry_obj) elif entry.event_type == 'ADE': entry_obj = {} data_env = entry.date_time if simple: text_com = _('Added empty cartridge user %(user_name)s.') % { 'user_name': entry.event_user } else: text_com = _( 'Added empty cartridge № %(cart_number)s (%(cart_type)s) user %(user_name)s.' ) % { 'cart_number': entry.cart_number, 'cart_type': entry.cart_type, 'user_name': entry.event_user } entry_obj['data_env'] = do_timezone(data_env, conf.time_zone) entry_obj['text_com'] = text_com frdly_es.append(entry_obj) elif entry.event_type == 'TR': entry_obj = {} data_env = entry.date_time if simple: text_com = _( 'Transfer to use %(event_org)s user %(event_user)s.') % { 'event_org': entry.event_org, 'event_user': entry.event_user } else: text_com = _( '№ %(cart_number)s (%(cart_type)s) transfer to use %(event_org)s user %(event_user)s.' ) % { 'cart_number': entry.cart_number, 'cart_type': entry.cart_type, 'event_org': entry.event_org, 'event_user': entry.event_user } entry_obj['data_env'] = do_timezone(data_env, conf.time_zone) entry_obj['text_com'] = text_com frdly_es.append(entry_obj) elif entry.event_type == 'TF': entry_obj = {} data_env = entry.date_time if simple: text_com = _( 'Transfer to restore "%(event_firm)s" user %(event_user)s.' ) % { 'event_firm': entry.event_firm, 'event_user': entry.event_user } else: text_com = _( '№ %(cart_number)s (%(cart_type)s) transfer to restore "%(event_firm)s" user %(event_user)s.' ) % { 'cart_number': entry.cart_number, 'cart_type': entry.cart_type, 'event_firm': entry.event_firm, 'event_user': entry.event_user } entry_obj['data_env'] = do_timezone(data_env, conf.time_zone) entry_obj['text_com'] = text_com frdly_es.append(entry_obj) elif entry.event_type == 'RS': entry_obj = {} data_env = entry.date_time action_text = '' if len(str(entry.cart_action)) == 5: # поддержка старых релизов severcart entry.cart_action = '00000' if entry.cart_action == 0 else entry.cart_action action_num = [int(i) for i in str(entry.cart_action)] action_text += _( 'filling and cleaning, ') if action_num[0] == 1 else '' action_text += _( 'Replacement fotoreceptor, ') if action_num[1] == 1 else '' action_text += _( 'replacement of squeegee, ') if action_num[2] == 1 else '' action_text += _( 'chip replacement, ') if action_num[3] == 1 else '' action_text += _('replacing the magnetic roller, ' ) if action_num[4] == 1 else '' elif len(str(entry.cart_action)) == 6: entry.cart_action = '000000' if entry.cart_action == 0 else entry.cart_action action_num = [int(i) for i in str(entry.cart_action)] action_text += _( 'regeneration, ') if action_num[0] == 1 else '' action_text += _( 'filling and cleaning, ') if action_num[1] == 1 else '' action_text += _( 'Replacement fotoreceptor, ') if action_num[2] == 1 else '' action_text += _( 'replacement of squeegee, ') if action_num[3] == 1 else '' action_text += _( 'chip replacement, ') if action_num[4] == 1 else '' action_text += _('replacing the magnetic roller, ' ) if action_num[5] == 1 else '' else: action_text = _('Not implement.') if simple: text_com = _( 'Return to the filling in the firm "%(event_firm)s" user %(event_user)s.' ) % { 'event_firm': entry.event_firm, 'event_user': entry.event_user } else: text_com = _( '№ %(cart_number)s (%(cart_type)s) return to the filling in the firm "%(event_firm)s" user %(event_user)s.' ) % { 'cart_number': entry.cart_number, 'cart_type': entry.cart_type, 'event_firm': entry.event_firm, 'event_user': entry.event_user } text_com += _('<br/>The following work: ') text_com += action_text entry_obj['data_env'] = do_timezone(data_env, conf.time_zone) entry_obj['text_com'] = text_com frdly_es.append(entry_obj) elif entry.event_type == 'TB': entry_obj = {} data_env = entry.date_time if simple: text_com = _('Moving in user to basket %(event_user)s.') % { 'event_user': entry.event_user, } else: text_com = _( '№ %(cart_number)s (%(cart_type)s) moving in user to basket %(event_user)s.' ) % { 'cart_number': entry.cart_number, 'cart_type': entry.cart_type, 'event_user': entry.event_user, } entry_obj['data_env'] = do_timezone(data_env, conf.time_zone) entry_obj['text_com'] = text_com frdly_es.append(entry_obj) elif entry.event_type == 'DC': entry_obj = {} data_env = entry.date_time if simple: text_com = _('Deleted user %(event_user)s.') % { 'event_user': entry.event_user } else: text_com = _( '№ %(cart_number)s (%(cart_type)s) deleted user %(event_user)s.' ) % { 'cart_number': entry.cart_number, 'cart_type': entry.cart_type, 'event_user': entry.event_user, } entry_obj['data_env'] = do_timezone(data_env, conf.time_zone) entry_obj['text_com'] = text_com frdly_es.append(entry_obj) elif entry.event_type == 'TS': entry_obj = {} data_env = entry.date_time if simple: text_com = _( 'Return to stock from %(event_org)s user %(event_user)s.' ) % { 'event_org': entry.event_org, 'event_user': entry.event_user, } else: text_com = _( '№ %(cart_number)s (%(cart_type)s) return to stock from %(event_org)s user %(event_user)s.' ) % { 'cart_number': entry.cart_number, 'cart_type': entry.cart_type, 'event_org': entry.event_org, 'event_user': entry.event_user } entry_obj['data_env'] = do_timezone(data_env, conf.time_zone) entry_obj['text_com'] = text_com frdly_es.append(entry_obj) elif entry.event_type == 'CN': entry_obj = {} data_env = entry.date_time if simple: text_com = _( '%(event_user)s produced has replaced the former number %(old_number)s new %(new_number)s.' ) % { 'old_number': entry.cart_old_number, 'new_number': entry.cart_number, 'event_user': entry.event_user, } else: text_com = _( '%(event_user)s changed number of cartridge %(old_number)s new %(new_number)s.' ) % { 'old_number': entry.cart_old_number, 'new_number': entry.cart_number, 'event_user': entry.event_user, } entry_obj['data_env'] = do_timezone(data_env, conf.time_zone) entry_obj['text_com'] = text_com frdly_es.append(entry_obj) return frdly_es
def show_event_page(request): """Передача списка событий исходя из номера пагинации. """ tmp_dict = dict() if not (request.user.is_authenticated()): # если пользователь не аутентифицирован, то ничего не возвращаем jsonr = json.dumps({'authenticated': False}) return JsonResponse(jsonr, safe=False) MAX_EVENT_LIST = settings.MAX_EVENT_LIST next_page = request.POST.get('next_page', '') try: next_page = int(next_page) except ValueError: next_page = 1 try: dept_id = request.user.departament.pk except AttributeError: dept_id = 0 list_events = Events.objects.filter(departament=dept_id).order_by('-pk') # возвращаем данные из сессионного словаря start_date = request.session['start_date'] end_date = request.session['end_date'] tmp_dict['has_next'] = 0 conf = SevercartConfigs() if start_date: st_year = int(start_date.get('year_value')) st_month = int(start_date.get('month_value')) st_date = int(start_date.get('date_value')) start_date = datetime.datetime(year=st_year, month=st_month, day=st_date, hour=0, minute=0, second=0, microsecond=0, tzinfo=pytz.timezone(conf.time_zone)) if end_date: en_year = int(end_date.get('year_value')) en_month = int(end_date.get('month_value')) en_date = int(end_date.get('date_value')) end_date = datetime.datetime(year=en_year, month=en_month, day=en_date, hour=0, minute=0, second=0, microsecond=0, tzinfo=pytz.timezone(conf.time_zone)) if start_date and not (end_date): list_events = list_events.filter(date_time__gte=start_date) elif not (start_date) and not (end_date): # выбираем все объекты если пользователь оставил поля ввода пустыми pass elif end_date and not (start_date): list_events = list_events.filter(date_time__lte=end_date) elif start_date == end_date: list_events = list_events.filter(date_time__year=end_date.year, date_time__month=end_date.month, date_time__day=end_date.day) elif start_date and end_date: # вторая дата не попадает в диапазон, поэтому приболяем к ней 1 день end_date = end_date + datetime.timedelta(days=1) list_events = list_events.filter( Q(date_time__lte=end_date) & Q(date_time__gte=start_date)) p = Paginator(list_events, MAX_EVENT_LIST) try: content = p.page(next_page) except PageNotAnInteger: # If page is not an integer, deliver first page. content = p.page(1) except EmptyPage: # If page is out of range (e.g. 9999), deliver last page of results. #content = paginator.page(paginator.num_pages) tmp_dict['stop_pagination'] = '1' return JsonResponse(tmp_dict, safe=False) next_page = next_page + 1 list_events = events_decoder(content, simple=False) html_content = '' for event_line in list_events: c = Context(dict(date_env=event_line.get('data_env', ''))) date_env = Template('{{ date_env|date:"d.m.Y G:i" }}').render(c) html_row = '<tr><td>%s</td><td>%s</td></tr>' % ( date_env, event_line.get('text_com', ''), ) html_content += html_row tmp_dict['html_content'] = html_content tmp_dict['stop_pagination'] = '0' tmp_dict['next_page'] = next_page # если страница имеет следующую, то добавляем кнопку просмотреть ещё, иначе не добавляем if content.has_next(): tmp_dict['has_next'] = 1 return JsonResponse(tmp_dict, safe=False)
def date_filter(request): """Загрузка списка событий в соответствии с диапазонами. """ ansver = dict() # для ajax ответа на запрос context = dict() # для рендеринга списка событий ansver['has_next'] = 0 try: dept_id = request.user.departament.pk except AttributeError: dept_id = 0 time_zone_offset = request.POST.get('time_zone_offset', 0) try: time_zone_offset = int(time_zone_offset) except ValueError: time_zone_offset = 0 next_page = request.POST.get('next_page', '') try: next_page = int(next_page) except ValueError: next_page = 1 MAX_EVENT_LIST = settings.MAX_EVENT_LIST # попадаем в эту ветку если пользователь нажал на кнопку Показать date_form = DateForm(request.POST) list_events = Events.objects.filter(departament=dept_id).order_by('-pk') if date_form.is_valid(): data_in_post = date_form.cleaned_data # получаем данные для инициализации начальными значаниями заполненной формы start_date = data_in_post.get('start_date', '') end_date = data_in_post.get('end_date', '') # сохраняем переданные даты в сессионном словаре, потом будем читать его значения из /events/api/ request.session['start_date'] = start_date request.session['end_date'] = end_date # приводим словари, содержащие компоненты дат к объекту datetime conf = SevercartConfigs() if start_date: st_year = int(start_date.get('year_value')) st_month = int(start_date.get('month_value')) st_date = int(start_date.get('date_value')) #start_date = datetime.datetime(st_year, st_month, st_date) start_date = datetime.datetime(year=st_year, month=st_month, day=st_date, hour=0, minute=0, second=0, microsecond=0, tzinfo=pytz.timezone( conf.time_zone)) if end_date: en_year = int(end_date.get('year_value')) en_month = int(end_date.get('month_value')) en_date = int(end_date.get('date_value')) #end_date = datetime.datetime(en_year, en_month, en_date) end_date = datetime.datetime(year=en_year, month=en_month, day=en_date, hour=23, minute=59, second=59, microsecond=0, tzinfo=pytz.timezone(conf.time_zone)) if start_date and not (end_date): list_events = list_events.filter(date_time__gte=start_date) elif not (start_date) and not (end_date): # выбираем все объекты если пользователь оставил поля ввода пустыми pass elif end_date and not (start_date): list_events = list_events.filter(date_time__lte=end_date) elif start_date and end_date: # вторая дата не попадает в диапазон, поэтому приболяем к ней 1 день #end_date = end_date + datetime.timedelta(days=1) list_events = list_events.filter( Q(date_time__lte=end_date) & Q(date_time__gte=start_date)) #p = Paginator(list_events, MAX_EVENT_LIST) p = Paginator(list_events, MAX_EVENT_LIST) try: content = p.page(next_page) except PageNotAnInteger: # If page is not an integer, deliver first page. content = p.page(1) except EmptyPage: # If page is out of range (e.g. 9999), deliver last page of results. #content = paginator.page(paginator.num_pages) ansver['has_next'] = content.has_next() return JsonResponse(ansver, safe=False) # context['count_events'] = list_events.count() context['next_page'] = next_page + 1 context['max_count_events'] = MAX_EVENT_LIST context['list_events'] = events_decoder(content, time_zone_offset, simple=False) html = render_to_string('events/show_all_events.html', context) ansver['html'] = html # если страница имеет следующую, то добавляем кнопку просмотреть ещё, иначе не добавляем if content.has_next(): ansver['has_next'] = 1 return JsonResponse(ansver)