[Django]-Pass QuerySet to Celery Task in Django 1.11

7👍

As you discovered you can’t pass a queryset to the task directly, because the task arguments must be serializable. Pickling is not a good ideal either as you don’t actually need to serialize the entire queryset.

Instead you should pass a list of object IDs to the task, and then fetch the queryset from the task itself.

brand_ids = Brand.objects.filter(shops__shop_name__in=[shop]).values_list('id', flat=True)
task_run = brand_count.delay(list(brand_ids))

values_list will give you a list of IDs for the brands.

Then, in your task, you recreate the queryset and do what you need with it:

@task()
def brand_count(brand_ids):
    queryset = Brand.objects.filter(id__in=brand_ids)
    queryset.annotate(amount_of_products=Count('products'))

Leave a comment