Выполнить действие администратора django как задачу сельдерея

Нормальные функции могут быть выполнены как действия администратора django. Я хочу экспортировать данные в виде файла CSV. Из-за размера данных, я пытаюсь выполнить это как задачу сельдерея. Но объекты модели, запроса, набора запросов и т. Д. Не могут быть переданы в задачу. Есть ли способ выполнить действия администратора в качестве задачи сельдерея.

1 ответ

Чтобы выполнить действие администратора из задачи сельдерея или из любого места (например, команда управления):

from celery import shared_task
from django.contrib import admin
from django.test.client import RequestFactory
from django.contrib.auth.models import User

@shared_task
def my_task(pk_of_model):
    '''
    Task executes a delete_selected admin action.
    '''

    # the queryset is the set of objects selected from the change list
    queryset = MyModel.objects.filter(pk=pk_of_model)

    # we use the django request factory to create a bogus request
    rf = RequestFactory()

    # the post data must reflect as if a user selected the action
    # below we use a 'delete' action and specify post:'post' to
    # simulate the user confirmed the delete

    request = rf.post(
        '/admin/app/model',   # url of the admin change list
        {
            '_selected_action': [m.pk for m in queryset],
            'action': 'delete_selected',
            'post': 'post', 
        }
    )

    # the request factory does not use any middlewares so we add our
    # system user - some admin user all the tasks and commands run as.
    request.user = User.objects.get(username='SYSTEM') # must exist

    # the admin site registry holds all the ModelAdmin
    # instances where our actions are declared
    admin.site._registry[MyModel].delete_selected(request, queryset)

Приведенный выше пример потерпит неудачу, потому что delete_selected действие опирается на messages промежуточное программное обеспечение и фабрика запросов не использует никакой. Можно заключить заключительную строку исполнения в try: ... except MessageFailure: pass но, скорее всего, вы будете выполнять свое собственное действие, в котором вы сможете проверить, включено ли промежуточное ПО для сообщений.

Другие вопросы по тегам