Bird
Raised Fist0
Djangoframework~10 mins

Defining tasks in Django - Step-by-Step Execution

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Concept Flow - Defining tasks
Create tasks.py file
Define task function
Use @shared_task decorator
Task registered with Celery
Task can be called asynchronously
Task executes in worker process
This flow shows how to define a task in Django using Celery: create a tasks.py file, define a function, decorate it, register it, and then call it asynchronously.
Execution Sample
Django
from celery import shared_task

@shared_task
def add(x, y):
    return x + y
Defines a simple Celery task named 'add' that adds two numbers asynchronously.
Execution Table
StepActionCode LineResult
1Import shared_task decoratorfrom celery import shared_taskshared_task available
2Apply @shared_task decorator@shared_taskadd registered as Celery task
3Define function add(x, y)def add(x, y):Function add created
4Function body executes when task runsreturn x + yReturns sum of x and y
5Task can be called asynchronouslyadd.delay(4, 6)Task sent to worker for execution
6Worker executes taskadd(4, 6)Returns 10 asynchronously
💡 Task definition completes after decorator; execution happens later asynchronously.
Variable Tracker
VariableStartAfter Task CallAfter Execution
xundefined44
yundefined66
resultundefinedundefined10
Key Moments - 2 Insights
Why do we use @shared_task decorator instead of calling the function directly?
The @shared_task decorator registers the function as a Celery task so it can run asynchronously in a worker process, as shown in execution_table step 2 and 5.
When does the function body actually run?
The function body runs later in a separate worker process after calling add.delay(), not immediately when defining the function (see execution_table step 6).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what happens at step 3?
AThe function add is executed immediately
BThe task is sent to the worker
CThe function add is registered as a Celery task
DThe function add is deleted
💡 Hint
Check the 'Result' column at step 3 in the execution_table.
At which step is the task sent to the worker for execution?
AStep 5
BStep 4
CStep 2
DStep 6
💡 Hint
Look for 'Task sent to worker' in the execution_table.
If you remove the @shared_task decorator, what changes in the execution?
AThe function will be registered as a task automatically
BThe function can still run asynchronously
CThe function will run synchronously when called
DThe function will not be defined
💡 Hint
Refer to the key moment about the role of @shared_task decorator.
Concept Snapshot
Defining tasks in Django with Celery:
- Create tasks.py in app
- Define function with @shared_task decorator
- Call task asynchronously with .delay()
- Task runs in worker process
- Decorator registers function as async task
Full Transcript
To define a task in Django using Celery, you create a tasks.py file in your app. Inside, you define a function and decorate it with @shared_task. This decorator registers the function as a Celery task, allowing it to run asynchronously. When you call the task using .delay(), the task is sent to a worker process which executes the function body later. Variables like function arguments are passed to the worker, and the result is returned asynchronously. Without the decorator, the function runs synchronously when called.

Practice

(1/5)
1. What decorator is commonly used to define a background task in Django with Celery?
easy
A. @task_runner
B. @shared_task
C. @async_task
D. @background_task

Solution

  1. Step 1: Understand task definition in Django with Celery

    Celery uses the @shared_task decorator to mark functions as tasks that can run asynchronously.
  2. Step 2: Identify the correct decorator

    Among the options, only @shared_task is the correct and standard decorator for defining tasks.
  3. Final Answer:

    @shared_task -> Option B
  4. Quick Check:

    Task decorator = @shared_task [OK]
Hint: Remember: Celery tasks use @shared_task decorator [OK]
Common Mistakes:
  • Using @background_task which is not a Celery decorator
  • Confusing @async_task with async/await syntax
  • Using @task_runner which is not valid in Django
2. Which of the following is the correct way to call a Celery task asynchronously in Django?
easy
A. my_task.run()
B. my_task.execute()
C. my_task.delay()
D. my_task.start()

Solution

  1. Step 1: Recall how to call Celery tasks asynchronously

    Celery tasks are called asynchronously using the delay() method on the task function.
  2. Step 2: Identify the correct method

    Only delay() triggers the task asynchronously; other methods like run() execute synchronously or do not exist.
  3. Final Answer:

    my_task.delay() -> Option C
  4. Quick Check:

    Async call method = delay() [OK]
Hint: Use delay() to run tasks asynchronously [OK]
Common Mistakes:
  • Calling run() which runs task synchronously
  • Using execute() which is not a Celery method
  • Trying start() which does not exist for tasks
3. Given this task definition:
from celery import shared_task

@shared_task
def add(x, y):
    return x + y

result = add.delay(4, 5)

What will result.get() return?
medium
A. 9
B. None
C. An AsyncResult object
D. A syntax error

Solution

  1. Step 1: Understand the task and its call

    The add function adds two numbers. Calling add.delay(4, 5) runs it asynchronously and returns an AsyncResult.
  2. Step 2: Using result.get() retrieves the task result

    Calling result.get() waits for the task to finish and returns the sum, which is 9.
  3. Final Answer:

    9 -> Option A
  4. Quick Check:

    Task result = 9 [OK]
Hint: delay() returns AsyncResult; get() fetches the actual result [OK]
Common Mistakes:
  • Thinking delay() returns the result immediately
  • Confusing AsyncResult object with the actual result
  • Expecting None because task runs asynchronously
4. Identify the error in this task definition:
from celery import shared_task

@shared_task
def multiply(x, y):
return x * y
medium
A. Function name is invalid
B. Missing @shared_task decorator
C. Using delay() incorrectly
D. Indentation error in function body

Solution

  1. Step 1: Check the function syntax

    The function body must be indented inside the function definition. Here, return x * y is not indented.
  2. Step 2: Identify the error type

    Python requires indentation for blocks. Missing indentation causes an IndentationError.
  3. Final Answer:

    Indentation error in function body -> Option D
  4. Quick Check:

    Python blocks need indentation [OK]
Hint: Check indentation inside function definitions [OK]
Common Mistakes:
  • Ignoring indentation errors
  • Assuming decorator is missing when it is present
  • Confusing function name validity with syntax errors
5. You want to define a task that sends emails but only if the email address is not empty. Which of these task definitions correctly applies this condition?
hard
A. from celery import shared_task @shared_task def send_email(email): if email: # send email code return 'Sent' return 'No email provided'
B. from celery import shared_task @shared_task def send_email(email): if email == None: return 'No email provided' # send email code return 'Sent'
C. from celery import shared_task @shared_task def send_email(email): if not email: return 'Sent' # send email code return 'No email provided'
D. from celery import shared_task def send_email(email): if email: # send email code return 'Sent' return 'No email provided'

Solution

  1. Step 1: Check for correct task decorator and condition

    from celery import shared_task @shared_task def send_email(email): if email: # send email code return 'Sent' return 'No email provided' uses @shared_task and checks if email: which correctly tests for a non-empty email.
  2. Step 2: Verify logic correctness

    from celery import shared_task @shared_task def send_email(email): if email: # send email code return 'Sent' return 'No email provided' returns 'Sent' only if email is truthy (not empty), else returns 'No email provided'. This matches the requirement.
  3. Final Answer:

    Option A correctly defines the task with the condition -> Option A
  4. Quick Check:

    Use if email: to check non-empty string [OK]
Hint: Use if email: to check non-empty strings in tasks [OK]
Common Mistakes:
  • Forgetting @shared_task decorator
  • Using if not email: incorrectly reversing logic
  • Not indenting task function properly