3

I have a Django Rest Framework ViewSet:

MyModelViewSet(generics.RetrieveUpdateDestroyAPIView):
    def perform_destroy(self, instance):
        # do something besides deleting the object

Now I'm writing a Celery periodic task that deletes expired objects based on a filter (let's say end_date < now).

I want the task to reuse and perform the same actions that are executed in the ViewSet's perform_destroy method.

Can this be done? How?
Thanks!

Noam Gal
  • 1,124
  • 1
  • 11
  • 15

1 Answers1

3

You can solve your issue by using Request in DRF, schedule a celery task to call the request. It works well, I've implemented this before.

Example code:

from rest_framework.request import Request as DRFRequest
from django.conf import settings
from django.http import HttpRequest
from your_module.views import MyModelViewSet

CELERY_CACHING_QUEUE = getattr(settings, "CELERY_CACHING_QUEUE", None)


def delete_resource(resource_pk: int) -> None:
    """
    This method helps to delete the resource by the id.
    """
    print(f'Starting deleting resource {resource_pk}...')

    request = HttpRequest()
    request.method = 'DELETE'
    request.META = {
        'SERVER_NAME': settings.ALLOWED_HOSTS[0],
        'SERVER_PORT': 443
    }
    drf_request = DRFRequest(request)

    # If your API need user has access permission,
    # you should handle for getting the value of
    # user_has_access_permission before
    # E.g. below
    # drf_request.user = user_has_access_permission

    try:
        view = MyModelViewSet(
            kwargs={
                'pk': resource_pk
            },
            request=drf_request
        )
        view.initial(drf_request)
        view.delete(drf_request)
    except (Exception, KeyError) as e:
        print(f'Cannot delete resource: {resource_pk}, error: {e}')
        return

    print(f'Finished deleting resource {resource_pk}...')


@task(name="delete_resource_task", queue=CELERY_CACHING_QUEUE)
def delete_resource_task(resource_pk: int) -> None:
    """
    Async task helps to delete resource.
    """
    delete_resource(resource_pk)

Vu Phan
  • 594
  • 3
  • 8