Not directly relevant to your celery question, but I would like to point 
you to a project of mine - 
https://django-modelqueryform.readthedocs.io/en/latest/ It lets you build 
search form that generates complex Q objects. It would replace a lot of you 
GET field checking and filtering on that view, and I  think make it much 
more maintainable.



On Wednesday, February 13, 2019 at 6:34:17 AM UTC-5, valentin jungbluth 
wrote:
>
> Hello guys,
>
> I'm working on my Django project and I need to integrate Celery to do 
> something.
> I'm using Django 1.11.20.
>
> *My context :*
>
> I have a template page with a search form. Once you did a search, it 
> returns a table with search results.
> It's possible to export to .xls format with/without search.
>
> There are 2 possibilities :
>
>
>    - If user wants to export *less than 70.000 objects*, the export 
>    creates an HttpResponse with download link.
>    - If user wants to export *more than 70.000 objects*, a Celery task 
>    has to be initiate, it creates the file, save it into the MEDIA folder and 
>    user gets an email with expirable download link.
>
> I'm trying to implement this second part.
>
> The check is done on template page with number of results according to the 
> search part. 
> If < 70.000 objects, export button calls *export_xls()* function, else it 
> calls the Celery task 
>
> *get_xls_export()HTML Template file :*
>
> {% if item_count > 0 and item_count < 70000 %}
>     {% if search_info_str %}
>       <a title="Print" href="{% url print_link model='finalproduct' 
> search_info=search_info_str %}" class="button btn btn-default 
> print_items"><span class="glyphicon glyphicon-print"></span></a>
>       <a title="Export to Excel" class="button btn btn-default" href="{% 
> url 'ocabr:export-xls' model=model search_info=search_info_str %}"><span 
> class="glyphicon glyphicon-export"></span></a>
>     {% else %}
>       <a title="Print" href="{% url print_link model='finalproduct' %}" 
> class="button btn btn-default print_items"><span class="glyphicon 
> glyphicon-print"></span></a>
>       <a title="Export to Excel" class="button btn btn-default" href="{% 
> url 'ocabr:export-xls' model=model %}"><span class="glyphicon 
> glyphicon-export"></span></a>
>     {% endif %}
> {% else %}
>     {% if search_info_str %}
>       <a title="Print" href="{% url print_link model='finalproduct' 
> search_info=search_info_str %}" class="button btn btn-default 
> print_items"><span class="glyphicon glyphicon-print"></span></a>
>       <a title="Export to Excel" name="export" value="export" 
> class="button btn btn-default" href="{% url 'ocabr:cron_export' model=model 
> search_info=search_info_str %}"><span class="glyphicon 
> glyphicon-export"></span></a>
>     {% else %}
>       <a title="Print" href="{% url print_link model='finalproduct' %}" 
> class="button btn btn-default print_items"><span class="glyphicon 
> glyphicon-print"></span></a>
>       <a title="Export to Excel" name="export" value="export" 
> class="button btn btn-default" href="{% url 'ocabr:cron_export' model=model 
> %}"><span class="glyphicon glyphicon-export"></span></a>
>     {% endif %}
> {% endif %}
>
> This part calls the right function depending on search result.
>
> *Case 1 : Less than 70.000 objects*
>
> The view associated to the previous HTML template is :
>
> class FinalProductListView(PermissionRequiredMixin, EdqmListSearchView):
>
>     model = FinalProduct
>     page_title = _('Final Products')
>     default_sort_params = ('manufacturer_name', 'asc')
>     sort_params = ['pk']
>
>     create_link = 'ocabr:finalproduct-add'
>     update_link = 'ocabr:finalproduct-edit'
>     delete_link = 'ocabr:finalproduct-delete'
>     view_link = 'ocabr:finalproduct-view'
>     print_link = 'ocabr:print-object'
>
>     permission_required = 'ocabr.view_finalproduct'
>
>     template_name = 'ocabr/final_product/final_product_search.html'
>
>     paginate_by = getattr(PaginationMixin, 'paginate_by', None)
>     headers = {
>         'releasing_body__short_name': 'Releasing Body/Institution',
>         'is_withdrawn': 'Is nullified',
>     }
>
>     # Configuration of fields
>     fields = ['manufacturer_name', 'releasing_body__short_name', 
> 'product_trade_name', 'pheur_name', 'name', 'final_bulk',
>               'decision', 'date_decision', 'is_withdrawn', 'member_state']
>
>     def get_queryset(self):
>         queryset = super(FinalProductListView, self).get_queryset()
>
>         date_format = settings.USER_DATE_FORMAT
>         # Add filter from search form.
>         if 'mah' in self.request.GET:
>             if self.request.GET['mah'] != '':
>                 queryset = 
> queryset.filter(mah__icontains=self.request.GET['mah'].strip())
>         if 'releasing_body' in self.request.GET:
>             if self.request.GET['releasing_body']:
>                 queryset = 
> queryset.filter(releasing_body__id=int(self.request.GET['releasing_body']))
>         if 'trade_name' in self.request.GET:
>             if self.request.GET['trade_name'] != '':
>                 queryset = 
> queryset.filter(product_trade_name__icontains=self.request.GET['trade_name'].strip())
>         if 'member_state' in self.request.GET:
>             if self.request.GET['member_state']:
>                 queryset = 
> queryset.filter(member_state__id=int(self.request.GET['member_state']))
>         if 'pheur_name' in self.request.GET:
>             if self.request.GET['pheur_name'] != '':
>                 queryset = 
> queryset.filter(pheur_name__id=self.request.GET['pheur_name'])
>         if 'decision' in self.request.GET:
>             if self.request.GET['decision']:
>                 queryset = 
> queryset.filter(decision__id=int(self.request.GET['decision']))
>         if 'final_bulk_num' in self.request.GET:
>             if self.request.GET['final_bulk_num'] != '':
>                 queryset = 
> queryset.filter(final_bulk__icontains=self.request.GET['final_bulk_num'].strip())
>         if 'domain' in self.request.GET:
>             if self.request.GET['domain']:
>                 queryset = 
> queryset.filter(domain__id=int(self.request.GET['domain']))
>         if 'manufacturer_name' in self.request.GET:
>             if self.request.GET['manufacturer_name'] != '':
>                 queryset = 
> queryset.filter(manufacturer_name__id=self.request.GET['manufacturer_name'])
>         if 'date_from' in self.request.GET and 'date_to' in 
> self.request.GET:
>             if self.request.GET['date_from'] and not 
> self.request.GET['date_to']:
>                 try:
>                     queryset = 
> queryset.filter(date_decision__gte=Utils.filter_date_format(self.request.GET['date_from'],
>  
> date_format))
>                 except:
>                     pass
>             if not self.request.GET['date_from'] and 
> self.request.GET['date_to']:
>                 try:
>                     queryset = 
> queryset.filter(date_decision__lte=Utils.filter_date_format(self.request.GET['date_to'],
>  
> date_format))
>                 except:
>                     pass
>             if self.request.GET['date_from'] and 
> self.request.GET['date_to']:
>                 try:
>                     queryset = 
> queryset.filter(date_decision__range=(Utils.filter_date_format(self.request.GET['date_from'],
>  
> date_format), Utils.filter_date_format(self.request.GET['date_to'], 
> date_format)))
>                 except:
>                     pass
>
>         if 'name' in self.request.GET:
>             if self.request.GET['name'] != '':
>                 queryset = 
> queryset.filter(name__icontains=self.request.GET['name'].strip())
>         if 'eu_cert_n' in self.request.GET:
>             if self.request.GET['eu_cert_n'] != '':
>                 queryset = 
> queryset.filter(eu_cert_n__icontains=self.request.GET['eu_cert_n'].strip())
>         if 'status' in self.request.GET:
>             if self.request.GET['status'] != '':
>                 queryset = 
> queryset.filter(status_final_product__icontains=self.request.GET['status'].strip())
>         if 'upstream_code_product' in self.request.GET:
>             if self.request.GET['upstream_code_product'] != '':
>                 queryset = 
> queryset.filter(upstream_products__name__icontains=self.request.GET['upstream_code_product'].strip())
>         if 'certificate_nullified' in self.request.GET:
>             if self.request.GET['certificate_nullified'] != '' and 
> self.request.GET['certificate_nullified'] != 'both':
>                 queryset = queryset.filter(
>                     is_withdrawn__icontains='t' if 
> self.request.GET['certificate_nullified'] == 'True' else 'f')
>
>         return queryset
>
>     def get_context_data(self, **kwargs):
>         """ Update the context data with query_string."""
>         context = super(EdqmListSearchView, 
> self).get_context_data(**kwargs)
>         context['total_records'] = self.get_total_count()
>         # Create or Update
>         if 'certificate_nullified' in self.request.GET:
>             form = FinalProductSearchForm(data=self.request.GET, 
> user=self.request.user)
>         else:
>             form = FinalProductSearchForm(user=self.request.user, 
> initial={'certificate_nullified': 'both'})
>
>         if not self.page_title:
>             self.page_title = _("List of ") + 
> str(self.model._meta.verbose_name_plural)
>
>         # Check perms
>         if 'add' in self.model._meta.default_permissions and not 
> self.request.user.has_perm(self.model._meta.app_label + '.add_' + 
> self.model._meta.model_name):
>             self.create_link = None
>         if 'change' in self.model._meta.default_permissions and not 
> self.request.user.has_perm(self.model._meta.app_label + '.change_' + 
> self.model._meta.model_name):
>             self.update_link = None
>         if 'delete' in self.model._meta.default_permissions and not 
> self.request.user.has_perm(self.model._meta.app_label + '.delete_' + 
> self.model._meta.model_name):
>             self.delete_link = None
>
>         # Send id to print info or excel.
>         search_text = ""
>         already_sorted = False
>         if 'csrfmiddlewaretoken' in self.request.GET:
>             # Log search form
>             Utils.log_search_form(self, 'Final product')
>
>             search_form_info = [str(info) + '=' + self.request.GET[info] 
> for info in self.request.GET if self.request.GET[info] != '' and info != 
> 'csrfmiddlewaretoken' and self.request.GET[info] != 'both' and info != 
> 'page']
>             is_date_to = False
>             is_date_from = False
>             for date_info in search_form_info:
>                 if 'date_from' in date_info:
>                     is_date_from = True
>                 if 'date_to' in date_info:
>                     is_date_to = True
>             is_range_date = True if is_date_to and is_date_from else False
>             d1 = ''
>             d2 = ''
>             for compute_txt in search_form_info:
>
>                 # Change filter name.
>                 if 'mah' in compute_txt:
>                     compute_txt = compute_txt.replace('mah', 
> 'mah__contains')
>                 elif 'sorting' in compute_txt:
>                     already_sorted = True
>                 elif 'releasing_body' in compute_txt:
>                     compute_txt = compute_txt.replace('releasing_body', 
> 'releasing_body__id')
>                 elif 'trade_name' in compute_txt:
>                     compute_txt = compute_txt.replace('trade_name', 
> 'product_trade_name__icontains')
>                 elif 'member_state' in compute_txt:
>                     compute_txt = compute_txt.replace('member_state', 
> 'member_state__id')
>                 elif 'pheur_name' in compute_txt:
>                     compute_txt = compute_txt.replace('pheur_name', 
> 'pheur_name__id')
>                 elif 'decision' in compute_txt:
>                     compute_txt = compute_txt.replace('decision', 
> 'decision__id')
>                 elif 'final_bulk_num' in compute_txt:
>                     compute_txt = compute_txt.replace('final_bulk_num', 
> 'final_bulk__icontains')
>                 elif 'domain' in compute_txt:
>                     compute_txt = compute_txt.replace('domain', 
> 'domain__id')
>                 elif 'manufacturer_name' in compute_txt:
>                     compute_txt = compute_txt.replace('manufacturer_name', 
> 'manufacturer_name__id')
>                 elif 'name' in compute_txt:
>                     compute_txt = compute_txt.replace('name', 
> 'name__icontains')
>                 elif 'eu_cert_n' in compute_txt:
>                     compute_txt = compute_txt.replace('eu_cert_n', 
> 'eu_cert_n__icontains')
>                 elif 'status' in compute_txt:
>                     compute_txt = compute_txt.replace('status', 
> 'status_final_product__icontains')
>                 elif 'upstream_code_product' in compute_txt:
>                     compute_txt = 
> compute_txt.replace('upstream_code_product', 
> 'upstream_products__name__icontains')
>                 elif 'certificate_nullified' in compute_txt:
>                     compute_txt = 
> compute_txt.replace('certificate_nullified', 'is_withdrawn__icontains')
>                     if 'True' in compute_txt:
>                         compute_txt = compute_txt.replace('True', 't')
>                     else:
>                         compute_txt = compute_txt.replace('False', 'f')
>
>                 date_format = settings.USER_DATE_FORMAT
>                 if not is_range_date:
>                     if 'date_from' in compute_txt and is_date_from and not 
> is_date_to:
>                         text_to_replace = compute_txt.split('=')[1]
>                         try:
>                             text_to_replace = Utils.change_date_format(
>                                 
> datetime.datetime.strptime(text_to_replace, date_format),
>                                 date_format).replace('/', '-')
>                         except ValueError:
>                             pass
>                         compute_txt = 
> compute_txt.replace(compute_txt.split('=')[1], text_to_replace)
>                         compute_txt = compute_txt.replace('date_from', 
> 'date_decision__gte')
>                     if 'date_to' in compute_txt and not is_date_from and 
> is_date_to:
>                         text_to_replace = compute_txt.split('=')[1]
>                         try:
>                             text_to_replace = 
> Utils.change_date_format(datetime.datetime.strptime(text_to_replace, 
> date_format), date_format).replace('/','-')
>                         except ValueError:
>                             pass
>                         compute_txt = 
> compute_txt.replace(compute_txt.split('=')[1], text_to_replace)
>                         compute_txt = compute_txt.replace('date_to', 
> 'date_decision__lte')
>                 else:
>                     if 'date_from' in compute_txt:
>                         text_to_replace = compute_txt.split('=')[1]
>                         try:
>                             text_to_replace = Utils.change_date_format(
>                                 
> datetime.datetime.strptime(text_to_replace, date_format),
>                                 date_format).replace('/', '-')
>                         except ValueError:
>                             pass
>                         d1 = 
> text_to_replace.replace(compute_txt.split('=')[1], text_to_replace)
>                         continue
>                     if 'date_to' in compute_txt:
>                         text_to_replace = compute_txt.split('=')[1]
>                         try:
>                             text_to_replace = 
> Utils.change_date_format(datetime.datetime.strptime(text_to_replace, 
> date_format), date_format).replace('/','-')
>                         except ValueError:
>                             pass
>                         d2 = 
> text_to_replace.replace(compute_txt.split('=')[1], text_to_replace)
>                         continue
>                 if d1 and d2:
>                     search_text += 'date_decision__gte=' + d1 + 
> ';date_decision__lte=' + d2 + ';'
>                     d1 = ''
>                     d2 = ''
>
>                 search_text += compute_txt + ';'
>             if search_text:
>                 search_text = search_text[:-1]
>
>         # Sorting patch
>         if not already_sorted:
>             if 'sorting' in self.request.GET and search_text == '':
>                 search_text = 'sorting=' + self.request.GET['sorting']
>
>         context.update({
>             'title': self.page_title,
>             'fields': self.fields,
>             'labels': self.get_labels(),
>             'view_link': self.view_link,
>             'create_link': self.create_link,
>             'update_link': self.update_link,
>             'delete_link': self.delete_link,
>             'search_link': self.search_link,
>             'export_links': self.export_links,
>             'model': str(self.model._meta.model_name),
>             'search_form': form,
>             'item_count': self.object_list.count(),
>             'print_link': self.print_link,
>             'search_info_str': search_text,
>             'limit_print_search': settings.LIMIT_PRINT_SEARCH
>
>         })
>
>         if not context.get('is_paginated', False):
>             return context
>
>         # Update paginator range
>         paginator = context.get('paginator')
>         num_pages = paginator.num_pages
>
>         current_page = context.get('page_obj')
>         page_no = current_page.number
>
>         if num_pages <= 10 or page_no <= 5:  # case 1 and 2
>             pages = [x for x in range(1, min(num_pages + 1, 11))]
>         elif page_no > num_pages - 4:  # case 4
>             pages = [x for x in range(num_pages - 9, num_pages + 1)]
>         else:  # case 3
>             pages = [x for x in range(page_no - 5, page_no + 5)]
>
>         context.update({'pages': pages})
>         return context
>
>
> In my template, I have a function export_xls() called when user press 
> "Export" button :
>
> class ExportOCABR(View):
>
>     def export_xls(self, model="", search_info=""):
>         app_label = 'ocabr'
>         its_fp_or_up_product = False
>         obsolete = False
>         if self.GET.get('obsolete', '') == 'True':
>             obsolete = True
>
>         default_sorting_key = ''
>         show_date_format = settings.USER_DATE_FORMAT
>         if model == "finalproduct" or model == "upstreamproduct":
>             its_fp_or_up_product = True
>             default_sorting_key = 'manufacturer_name' if model == 
> "finalproduct" else 'releasing_body__short_name'
>         if model == "releasebodyinstitution":
>             default_sorting_key = 'name'
>
>         model = apps.get_model(app_label=app_label, model_name=model)
>
>         # create a workbook in memory
>         output = io.BytesIO()
>
>         book = Workbook(output, {'constant_memory': True})
>         sheet = book.add_worksheet('Page 1')
>         # Sheet header, first row
>         row_num = 0
>
>         columns = model.export_field_excel()
>         rows_width_max = {}
>         bold_format = book.add_format({'bold': True})
>         max_col_width = []
>
>         for col_num in range(len(columns)):
>             rows_width_max[col_num] = columns[col_num].__len__()
>             sheet.write(row_num, col_num, columns[col_num], bold_format)
>             max_col_width.append(len(columns[col_num]) if 
> len(columns[col_num]) > 10 else 10)
>
>         default_sorting = True
>         sorting_key = ''
>         # Define search get all object or sorted value.
>         if search_info != '':
>             create_filters = search_info.split(';')
>             if create_filters.__len__() == 1:
>                 if 'sorting' in create_filters[0]:
>                     default_sorting = False
>                     sorting_key = 
> create_filters[0].split('=')[1].replace('~', '-')
>                     search_info = ''
>             else:
>                 for criter in create_filters:
>                     if 'sorting' in criter:
>                         default_sorting = False
>                         sorting_key = criter.split('=')[1].replace('~', 
> '-')
>                         search_info = search_info.replace(criter, "")
>                         search_info = search_info[:-1]
>
>         objects = model.objects.all()
>
>         if not its_fp_or_up_product:
>             if obsolete:
>                 objects = objects.obsolete()
>             else:
>                 objects = objects.active()
>
>         if sorting_key:
>             objects = objects.order_by(sorting_key, 'pk')
>
>         if default_sorting:
>             objects = objects.order_by(default_sorting_key, 'pk')
>
>         if search_info != '':
>             create_filters = search_info.split(';')
>             for search_filter in create_filters:
>                 search_filter = search_filter.split('=')
>                 try:
>                     if search_filter[1]:
>                         objects = objects.filter(**{search_filter[0]: 
> search_filter[1]})
>                 except:
>                     # Crud patch search
>                     if search_filter[0] == 'q':
>                         search_info = search_info.replace('q=', '')
>                     objects = objects.filter(get_query(search_info, 
> model.get_xls_values_list()))
>
>         rows = objects.values_list(*model.get_xls_values_list())
>         # Part which export file directly if less than 70.000 entries else 
> create file with download link
>
>         for row in rows:
>             row_num += 1
>             for col_num in range(len(row)):
>                 # Patch True False for boolean field
>                 is_bool = False
>                 if type(row[col_num]) is bool:
>                     is_bool = True
>
>                 if col_num in model.get_date_field_number():
>                     if row[col_num]:
>                         sheet.write(row_num, col_num, 
> row[col_num].strftime(show_date_format))
>                 else:
>                     if is_bool:
>                         sheet.write(row_num, col_num, 'True' if 
> row[col_num] else 'False')
>                     else:
>                         sheet.write(row_num, col_num, row[col_num])
>
>                 if len(str(row[col_num])) > max_col_width[col_num]:
>                     max_col_width[col_num] = len(str(row[col_num]))
>
>         # AutoFit col
>         for col_num in range(len(columns)):
>             sheet.set_column(col_num, col_num, max_col_width[col_num] + 1)
>
>         book.close()
>
>         # construct response
>         output.seek(0)
>         name = 'Obsolete' if obsolete else ''
>         name += str(model._meta.verbose_name_plural)
>         response = HttpResponse(output.read(),
>                                 
> content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
>         response['Content-Disposition'] = 'attachment; filename="' + name 
> + '.xlsx"'
>
>         return response
>
> The url file looks like :
>
> app_name = 'ocabr'
>
>
> urlpatterns = [
>
> # Final Product
>     url(r'^finalproduct/list/$', FinalProductListView.as_view(), name=
> 'finalproduct-list'),
>
> # Excel export list
>     url(r'export/xls/(?P<model>[-\w]+)/$', ExportOCABR.export_xls, name=
> 'export-xls'),
>     url(r'export/xls/(?P<model>[-\w]+)/(?P<search_info>.*)/$', ExportOCABR
> .export_xls, name='export-xls'),
> ]
>
>
> *Case 2 : More than 70.000 objects*
>
> I have a tasks.py file :
>
> @shared_task(bind=True, time_limit=3600, soft_time_limit=3600)
> def get_xls_export(self, model="", search_info=""):
>     app_label = 'ocabr'
>     its_fp_or_up_product = False
>     obsolete = False
>     if self.GET.get('obsolete', '') == 'True':
>         obsolete = True
>
>     default_sorting_key = ''
>     show_date_format = settings.USER_DATE_FORMAT
>     if model == "finalproduct" or model == "upstreamproduct":
>         its_fp_or_up_product = True
>         default_sorting_key = 'manufacturer_name' if model == 
> "finalproduct" else 'releasing_body__short_name'
>     if model == "releasebodyinstitution":
>         default_sorting_key = 'name'
>
>     model = apps.get_model(app_label=app_label, model_name=model)
>
>     # create a workbook in memory
>     output = io.BytesIO()
>
>     book = Workbook(output, {'constant_memory': True})
>     sheet = book.add_worksheet('Page 1')
>     # Sheet header, first row
>     row_num = 0
>
>     columns = model.export_field_excel()
>     rows_width_max = {}
>     bold_format = book.add_format({'bold': True})
>     max_col_width = []
>
>     for col_num in range(len(columns)):
>         rows_width_max[col_num] = columns[col_num].__len__()
>         sheet.write(row_num, col_num, columns[col_num], bold_format)
>         max_col_width.append(len(columns[col_num]) if 
> len(columns[col_num]) > 10 else 10)
>
>     default_sorting = True
>     sorting_key = ''
>     # Define search get all object or sorted value.
>     if search_info != '':
>         create_filters = search_info.split(';')
>         if create_filters.__len__() == 1:
>             if 'sorting' in create_filters[0]:
>                 default_sorting = False
>                 sorting_key = create_filters[0].split('=')[1].replace('~', 
> '-')
>                 search_info = ''
>         else:
>             for criter in create_filters:
>                 if 'sorting' in criter:
>                     default_sorting = False
>                     sorting_key = criter.split('=')[1].replace('~', '-')
>                     search_info = search_info.replace(criter, "")
>                     search_info = search_info[:-1]
>
>     objects = model.objects.all()
>
>     if not its_fp_or_up_product:
>         if obsolete:
>             objects = objects.obsolete()
>         else:
>             objects = objects.active()
>
>     if sorting_key:
>         objects = objects.order_by(sorting_key, 'pk')
>
>     if default_sorting:
>         objects = objects.order_by(default_sorting_key, 'pk')
>
>     if search_info != '':
>         create_filters = search_info.split(';')
>         for search_filter in create_filters:
>             search_filter = search_filter.split('=')
>             try:
>                 if search_filter[1]:
>                     objects = objects.filter(**{search_filter[0]: 
> search_filter[1]})
>             except:
>                 # Crud patch search
>                 if search_filter[0] == 'q':
>                     search_info = search_info.replace('q=', '')
>                 objects = objects.filter(get_query(search_info, 
> model.get_xls_values_list()))
>
>     rows = objects.values_list(*model.get_xls_values_list())
>     # Part which export file directly if less than 70.000 entries else 
> create file with download link
>
>     for row in rows:
>         row_num += 1
>         for col_num in range(len(row)):
>             # Patch True False for boolean field
>             is_bool = False
>             if type(row[col_num]) is bool:
>                 is_bool = True
>
>             if col_num in model.get_date_field_number():
>                 if row[col_num]:
>                     sheet.write(row_num, col_num, 
> row[col_num].strftime(show_date_format))
>             else:
>                 if is_bool:
>                     sheet.write(row_num, col_num, 'True' if row[col_num] 
> else 'False')
>                 else:
>                     sheet.write(row_num, col_num, row[col_num])
>
>             if len(str(row[col_num])) > max_col_width[col_num]:
>                 max_col_width[col_num] = len(str(row[col_num]))
>
>     # AutoFit col
>     for col_num in range(len(columns)):
>         sheet.set_column(col_num, col_num, max_col_width[col_num] + 1)
>
>     book.close()
>     output.seek(0)
>     name = 'Obsolete' if obsolete else ''
>     name += str(model._meta.verbose_name_plural)
>
>     name = name + "_" + str(datetime.now().strftime("%Y_%m_%d_%H_%M_%s")) 
> + '.xlsx'
>     default_storage.save(name, output)
>
>     # Send mail to django admin
>     receiver = settings.CRON_RECEIVER_MESSAGE
>     message = "Hello, \n \n" \
>               "This is an automatically generated e-mail. \n \n " \
>               "On " + str(
>         datetime.now()) + " with export file " + name + " available there 
> : " + settings.MEDIA_ROOT + "/" + name
>
>     try:
>         send_mail(
>             '[TEST database] Export file generated by OCABR',
>             message, 'nor...@test.fr <javascript:>',
>             receiver)
>     except ConnectionRefusedError as e:
>         return ['error_message', _('Error for sending email')]
>     return ['success_message', _('Generation of export file is done')]
>
> It's similar than *export_xls()* function, but the end is a bit 
> different. Because I don't create an HttpResponse, but I save the file in 
> MEDIA folder and send an email to user.
>
> *My question :*
>
> How and where I can create a *get_xls_export.delay()* when user click on 
> the export button for more than 70.000 objects ? How I can call it from 
> urls.py file ?
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/8e820ed8-8de0-4e0b-b712-76ce6d7ae20e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to