简体   繁体   English

我正在尝试将 celery 应用于 django 中基于 Class 的视图(apis)。 我怎样才能做到这一点?

[英]I'm trying to apply celery to Class based view(apis) in django. How can I do this?

Is it a correct way to apply celery to class based views?将 celery 应用于基于 class 的视图是否正确? And, if it is, how can I apply celery to class based Views?而且,如果是,我如何将 celery 应用于基于 class 的视图? I can't apply just tagging @app.task above functions inside class.我不能只在 class 中的函数上方应用标记 @app.task。

class ScheduleByFranchiseIdView(generics.RetrieveAPIView):
permission_classes = (IsAdmin,)
serializer_class = ScheduleSerializer
@app2.task
def get(self, request, franchise_id, start = None, end = None):
    if start != None and end != None:
        query1 = Q(student__profile__franchise__exact=franchise_id)
        query2 = Q(start_time__gte=start)
        query3 = Q(end_time__lt=end)
        queryset = Schedule.objects.filter(query1 & query2 & query3).exclude(status=ScheduleStatus.DELETED).order_by('-id')
        serializer = ScheduleSerializer(queryset, many=True)
    else:
        query1 = Q(student__profile__franchise__exact=franchise_id)
        queryset = Schedule.objects.filter(query1).exclude(status=ScheduleStatus.DELETED).order_by('-id')
        serializer = ScheduleSerializer(queryset, many=True)

    return Response(serializer.data)

I'm trying to test this api and when I call HTTP GET Method to call this api, i get the error below:我正在尝试测试这个 api,当我调用 HTTP GET 方法来调用这个 api 时,我得到以下错误:

Traceback (most recent call last):
  File "C:\Users\Tonyscoding\Desktop\TOCOL\TOCOL_backend\api\testing\test_pagination.py", line 154, in test_admin_schedule_pagination
    response = self.client.get('/api/schedule/by/franchise/simple/1/')
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\test.py", line 286, in get
    response = super().get(path, data=data, **extra)
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\test.py", line 203, in get
    return self.generic('GET', path, **r)
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\test.py", line 232, in generic
    method, path, data, content_type, secure, **extra)
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\test\client.py", line 422, in generic
    return self.request(**r)
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\test.py", line 283, in request
    return super().request(**kwargs)
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\test.py", line 235, in request
    request = super().request(**kwargs)
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\test\client.py", line 503, in request
    raise exc_value
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\django\views\generic\base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\views.py", line 505, in dispatch
    response = self.handle_exception(exc)
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\views.py", line 465, in handle_exception
    self.raise_uncaught_exception(exc)
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\views.py", line 476, in raise_uncaught_exception
    raise exc
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\rest_framework\views.py", line 502, in dispatch
    response = handler(request, *args, **kwargs)
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\celery\local.py", line 191, in __call__
    return self._get_current_object()(*a, **kw)
  File "C:\Users\Tonyscoding\Desktop\TOCOL\venv\lib\site-packages\celery\app\task.py", line 392, in __call__
    return self.run(*args, **kwargs)
TypeError: get() missing 1 required positional argument: 'request'

my celery worker get the task.我的 celery 工人得到了任务。 I think it's not a worker problem..我认为这不是工人的问题..

In your case might work next scenario.在您的情况下,下一个场景可能会起作用。 Create a task for hard workload:为繁重的工作量创建一个任务:

@app.task
def schedule_by_franchise(franchise_id, start=None, end=None):
    # Do some slow workload, filtering by non-indexed fields or something.
    if start is not None and end is not None:  # is not None ~20% faster than != None
        query1 = Q(student__profile__franchise__exact=franchise_id)
        query2 = Q(start_time__gte=start)
        query3 = Q(end_time__lt=end)
        queryset = Schedule.objects.filter(query1 & query2 & query3).exclude(status=ScheduleStatus.DELETED).order_by('-id')
    else:
        query1 = Q(student__profile__franchise__exact=franchise_id)
        queryset = Schedule.objects.filter(query1).exclude(status=ScheduleStatus.DELETED).order_by('-id')

    # Returns something serializable and what could be used for more faster DB search (founded object primary keys might fits)
    return tuple(queryset.values_list('id', flat=True))

When executed first GET you should create Celery task and then save it TASK_ID somewhere to later get result:第一次执行 GET 时,您应该创建 Celery 任务,然后将其 TASK_ID 保存在某处以便稍后获得结果:

from celery.result import AsyncResult


class ScheduleByFranchiseIdView(generics.RetrieveAPIView):
    permission_classes = (IsAdmin,)
    serializer_class = ScheduleSerializer

    def get(self, request, franchise_id, start=None, end=None, task_id=None):
        if not task_id:
            task = schedule_by_franchise.delay(franchise_id, start, end)
            return Response({
                'task': task.task_id,
                'status': 'processing',
                'message': f'Please, try again in 10 seconds with following task_id={task.task_id}',
            })
        else:
            result = AsyncResult(task_id)
            if result.ready():
                ids = result.result
                queryset = Schedule.objects.filter(id__in=ids)
                serializer = ScheduleSerializer(queryset, many=True)
                return Response(serializer.data)
            else:
                return Response({
                    'status': 'not_ready_yet',
                    'message': 'Please, try again in 5 seconds',
                })

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我正在尝试在 django 中制作 model。 但错误。 为什么? - I'm trying to make model in django. but error. why? 我正在尝试使用 django 登录。 但总是失败。 为什么? - I'm trying to login with django. but always fail. why? django。 我该如何在模型中做一些数学运算 - django. how can i do some math in model 当我在基于 class 的视图中应用过滤器时,如何在 django 中使用分页分页。 url 总是不断变化我如何跟踪 url - How do i use pagination pagination in django when i apply filters in class based view. the url always keeps changing how can i track the url 如何从django rest框架类基于创建视图的用户个人资料上的M2M字段中添加对象? - How can I add an object to a M2M field on my users profile from django rest frameworks class based create view? 请我是 python 的新手,我正在尝试使用 Django 做一个食谱应用程序。 我遇到了一个错误,即“UnboundLocalError:局部变量形式 - Please I'm new to python and I'm trying to do a recipe app using Django. I encountered an error which is "UnboundLocalError: local variable form 我可以将pk(主键)设置为django中的动态数字吗? 如果没有,那么如何设置动态变量? - Can I set pk(primary key) as a dynamic number in django. If not then how do I set a variable to be dynamic? 如何将参数传递给django中基于类的视图? - How do i pass parameters to a class based view in django? 我应该使用普通的Python代码还是Celery? Django的。 - Should I use plain Python code or Celery? Django. 如何解决 django 中的 ValueError。 异常值:ModelForm 没有指定 model class - How can I solve ValueError in django. Exception Value: ModelForm has no model class specified
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM