![](/img/trans.png)
[英]Django - Execute Celery task with options but no function arguments
[英]Django export function and Celery task
我想使用Celery來異步運行我的任務,因此遇到了一些麻煩。 我想通過導出方法創建一個數據文件。
內容:
用戶可以將搜索結果導出到.xlsx文件。 但是有兩種情況:
HttpResponse
直接下載生成的輸出文件。 我正在研究第二部分,但遇到設置芹菜任務的問題。
我的代碼:
這是用於在我的HTML模板中執行Celery任務的按鈕:
{% if 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" name="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" class="button btn btn-default" href="{% url 'ocabr:cron_export' model=model %}"><span class="glyphicon glyphicon-export"></span></a>
{% endif %}
{% endif %}
感謝這個urls.py文件,該按鈕調用了我的函數:
app_name = 'ocabr'
urlpatterns = [
# URL for the previous HTML template
url(r'^finalproduct/list/$', FinalProductListView.as_view(), name='finalproduct-list'),
# URL which calls Celery function
url(r'^cron_export/(?P<model>[-\w]+)/(?P<search_info>.*)/$', CronExport.as_view(), name='cron_export'),
url(r'^cron_export/(?P<model>[-\w]+)/$', CronExport.as_view(), name='cron_export'),
]
然后,在cron.py文件中定義該類:
class CronExport(View):
def export_xls_celery(self, request, *args, **kwargs):
get_xls_export.delay(**kwargs)
result = ['success_message', _('You will receive email in few minutes with result of data correction')]
return render(request, 'ocabr/final_product/final_product_search.html', {result[0]: result[1]})
def get(self, request, **kwargs):
self.export_xls_celery(self.request)
return render(request, 'ocabr/final_product/final_product_search.html')
函數get_xls_export()
調用task.py文件,該文件包含導出功能:
@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
# some code with columns adjust, ..
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, 'noreply@test.fr',
receiver)
except ConnectionRefusedError as e:
return ['error_message', _('Error for sending email')]
return ['success_message', _('Generation of export file is done')]
問題:
這是我單擊導出按鈕時得到的:
Exception Type: NoReverseMatch at /cron_export/finalproduct/
Exception Value: Reverse for '' not found. '' is not a valid view function or pattern name.
我有點迷茫,我沒克服要開始我的芹菜任務
編輯:
這是我的final_product_search.html文件:
{% extends 'list_crud/base.html' %}
{% load staticfiles %}
{% load i18n %}
{% load crispy_forms_tags %}
{% load is_date %}
{% block content %}
<h2>{% trans title %}</h2>
{# Add record function #}
{% if create_link %}
<a class="button btn btn-default" href="{% url create_link %}" title="{% trans 'Add a Final Product to database' %}">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</a>
{% endif %}
{% 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 %}
{% if create_link or export_links %}<br><br>{% endif %}
{# Search form #}
<form id="form_search" class="navbar-search" method="GET" action="{{ url }}">
{% csrf_token %}
<div class="row">
<div class="col-md-5">
{{ search_form.mah|as_crispy_field}}
</div>
<div class="col-md-5">
{{ search_form.releasing_body|as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-md-5">
{{ search_form.trade_name|as_crispy_field}}
</div>
<div class="col-md-5">
{{ search_form.member_state|as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-md-5">
{{ search_form.pheur_name|as_crispy_field}}
</div>
<div class="col-md-5">
{{ search_form.decision|as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-md-5">
{{ search_form.final_bulk_num|as_crispy_field}}
</div>
<div class="col-md-5">
{{ search_form.domain|as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-md-5">
{{ search_form.manufacturer_name|as_crispy_field}}
</div>
<div class="col-md-5">
{{ search_form.date_from|as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-md-5">
{{ search_form.name|as_crispy_field}}
</div>
<div class="col-md-5">
{{ search_form.date_to|as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-md-5">
{{ search_form.eu_cert_n|as_crispy_field}}
</div>
<div class="col-md-5">
{{ search_form.status|as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-md-5">
{{ search_form.upstream_code_product|as_crispy_field}}
</div>
<div class="col-md-5">
<label for="id_certificate_nullified" class="control-label ">
Certificate nullified
</label>
{{ search_form.certificate_nullified }}
</div>
</div>
<br>
<input type="submit" class="btn btn-default" value="{% trans 'Search' %}" />
<input type="button" class="btn btn-default" name="clear" value="Reset" onclick="clearForm(this.form);">
</form>
<br><br>
{% if query_string %}
<p class="text-info">Search results for <strong>{{ query_string }}</strong></p>
{% endif %}
{% block filter_bar %}
{% endblock %}
{# List of results #}
{% if object_list %}
{% with total=item_count %}
{{ total }} record{{ total|pluralize }} / {{ total_records }}
{% endwith %}
{% block list_table %}
<table id="table_{{ model }}" class="table table-bordered table-striped table-condensed table_model" style="table-layout:fixed; word-wrap: break-word;">
{# Headers #}
<thead>
<tr>
{% for item in fields %}
<th id="head_{{ item }}">
{% if sort_by == item %}
{% if order == 'asc' %}
<a href="?{% url_replace request 'sorting' '~'|add:item %}">
{{ labels|get_key:item }} </a>
<span class="glyphicon glyphicon-chevron-up align-right pull-right" aria-hidden="true"></span>
{% else %}
<a href="?{% url_replace request 'sorting' item %}">
{{ labels|get_key:item }} </a>
<span class="glyphicon glyphicon-chevron-down align-right pull-right" aria-hidden="true"></span>
{% endif %}
{% else %}
<a href="?{% url_replace request 'sorting' item %}">
{{ labels|get_key:item }}
</a>
{% endif %}
</th>
{% endfor %}
{% block extra_field_header %}{% endblock %}
{% if update_link or delete_link or view_link %}
<th class="action_list"></th>
{% endif %}
</tr>
</thead>
{# Rows #}
<tbody>
{% for item in object_list %}
<tr id="tr_{{ item.pk }}">
{% block default_values %}
{% with values=item|get_ordered_values:fields %}
{% for value in values %}
<td>
{% if value is not none %}
{{ value }}
{% endif %}
</td>
{% endfor %}
{% endwith %}
{% endblock %}
{% block extra_field_body %}{% endblock %}
{% block actions %}
{% if update_link or delete_link or view_link %}
<td>
{% if view_link %}
<a class="btn btn-default btn-xs" href="{% url view_link pk=item.pk %}" title="View">
<span class="glyphicon glyphicon-eye-open"></span>
</a>
{% endif %}
{% if update_link %}
<a class="btn btn-default btn-xs" href="{% url update_link pk=item.pk %}" title="Edit">
<span class="glyphicon glyphicon-pencil"></span>
</a>
{% endif %}
{% if delete_link %}
<a class="btn btn-default btn-xs" href="{% url delete_link pk=item.pk %}" title="Delete">
<span class="glyphicon glyphicon-trash"></span>
</a>
{% endif %}
</td>
{% endif %}
{% endblock %}
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% else %}
<div class="alert alert-warning" role="alert">{% trans "Nothing found" %}</div>
{% endif %}
{# Pagination #}
{% include 'list_crud/pagination.html' %}
{% block extra_html %}
{% endblock %}
{% endblock %}
我也遇到芹菜問題:
[2019-02-13 16:15:48,085: ERROR/ForkPoolWorker-4] Task ocabr.tasks.get_xls_export[85cb15ea-1443-4ce6-8832-ce5e8a14a4ca] raised unexpected: AttributeError("'Context' object has no attribute 'GET'",)
Traceback (most recent call last):
File "/home/.pyenv/versions/3.6.2/envs/ocabr/lib/python3.6/site-packages/celery/app/trace.py", line 382, in trace_task
R = retval = fun(*args, **kwargs)
File "/home/.pyenv/versions/3.6.2/envs/ocabr/lib/python3.6/site-packages/celery/app/trace.py", line 641, in __protected_call__
return self.run(*args, **kwargs)
File "/home/Bureau/Projets/ocabr/src/ocabr/tasks.py", line 26, in get_xls_export
if self.GET.get('obsolete', '') == 'True':
AttributeError: 'Context' object has no attribute 'GET'
您沒有將kwargs
從get
處理程序傳遞到export xlsx方法:
def get(self, request, **kwargs):
self.export_xls_celery(request, **kwargs)
此外,似乎您想訪問任務中的請求實例屬性。 不幸的是,這是不可能的-做到這一點的最佳方法是將所需的參數作為附加參數傳遞。 因此,在任務中:
@shared_task(bind=True, time_limit=3600, soft_time_limit=3600)
def get_xls_export(self, model="", search_info="", query_params=None):
app_label = 'app'
its_fp_or_up_product = False
query_params = query_params or {}
obsolete = False
if query_params.get('obsolete', '') == 'True':
obsolete = True
在任務調用中:
def export_xls_celery(self, request, *args, **kwargs):
get_xls_export.delay(query_params=request.GET, **kwargs)
result = ['success_message', _('You will receive email in few minutes with result of data correction')]
return render(request, 'app/final_product/final_product_search.html', {result[0]: result[1]})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.