<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Daeen Choi</title>
    <description>The latest articles on DEV Community by Daeen Choi (@daeenchoi).</description>
    <link>https://dev.to/daeenchoi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F564218%2F59b74dbf-dfc0-4282-85b9-fc4e0fc2ed30.jpg</url>
      <title>DEV Community: Daeen Choi</title>
      <link>https://dev.to/daeenchoi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/daeenchoi"/>
    <language>en</language>
    <item>
      <title>Database Scheduler with celery beat and manage schedule in Django admin</title>
      <dc:creator>Daeen Choi</dc:creator>
      <pubDate>Sat, 20 Feb 2021 14:29:03 +0000</pubDate>
      <link>https://dev.to/daeenchoi/database-scheduler-with-celery-beat-and-manage-schedule-in-django-admin-il5</link>
      <guid>https://dev.to/daeenchoi/database-scheduler-with-celery-beat-and-manage-schedule-in-django-admin-il5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Must read previous post first before reading this one :D&lt;br&gt;
&lt;a href="https://dev.to/paige0701/understanding-celery-and-creating-simple-task-in-django-3gdk"&gt;Previous Post about celery&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Aim of this post
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Install celery beat in django project and understand how it is used&lt;/li&gt;
&lt;li&gt;Settings for sending emails in django project using gmail&lt;/li&gt;
&lt;li&gt;Create a task that sends email&lt;/li&gt;
&lt;li&gt;Create schedule using django admin and integrate it with email task
Eg) Send notification email to users every Fridays at 4 a.m.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What is celery beat?
&lt;/h3&gt;

&lt;p&gt;celery beat is a scheduler. When it's time to run the task, it delivers the entry to the worker node. (Periodic task execution)&lt;/p&gt;

&lt;p&gt;Install celery beat&lt;br&gt;
&lt;code&gt;pip install django-celery-beat&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Migrate - Tables will be created to store tasks and schedules&lt;br&gt;
&lt;code&gt;python manage.py migrate&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;settings.py&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

INSTALLED_APPS = (
    ...,
    'django_celery_beat',
)


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Settings for emails
&lt;/h3&gt;

&lt;p&gt;1 . Click &lt;code&gt;Manage your Google Account&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadw1tscyb7l7mv8j9w7h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadw1tscyb7l7mv8j9w7h.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
2 . Make sure &lt;code&gt;2 step verification&lt;/code&gt; is on in Security &amp;gt; 2 step verification&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcijmkmugcsguhght2v1n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcijmkmugcsguhght2v1n.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
3 . Create &lt;code&gt;app password&lt;/code&gt;. App passwords &amp;gt; select app &amp;gt; other &amp;gt; Name it whatever! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61hbd1ldipfl7p4f6r6f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F61hbd1ldipfl7p4f6r6f.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
4 . Add &lt;code&gt;settings.py&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

# e-mail settings
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = {YOUR EMAIL ADDRESS}
EMAIL_HOST_PASSWORD = {YOUR PASSWORD FROM NO.3}
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Email setting is finished!&lt;/p&gt;



&lt;h3&gt;
  
  
  Where does celery beat store tasks and schedules?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Default entries are taken from the &lt;code&gt;beat_schedule&lt;/code&gt; setting
&lt;/h4&gt;

&lt;p&gt;task.py&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

app.conf.beat_schedule = {
  'add-every-30-seconds': {
        'task': 'tasks.add',
        'schedule': 30.0,
        'args': (16, 16)
    },
}
app.conf.timezone = 'UTC'


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
Or if you want more control over your schedules use &lt;code&gt;crontab&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

from celery.schedules import crontab

app.conf.beat_schedule = {
    # Executes every Monday morning at 7:30 a.m.
    'add-every-monday-morning': {
        'task': 'tasks.add',
        'schedule': crontab(hour=7, minute=30, day_of_week=1),
        'args': (16, 16),
    },
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Start celery beat service &lt;br&gt;
&lt;code&gt;celery -A &amp;lt;project name&amp;gt; beat&lt;/code&gt;&lt;/p&gt;



&lt;h4&gt;
  
  
  2 . Use custom stores - I will store them in database
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Let's create a task that sends email to users
```
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;@app.task(name="send_notification", bind=True, default_retry_delay=300, max_retries=5)&lt;br&gt;
def send_notification(self, subject, message):&lt;br&gt;
    from django.core.mail import send_mail as sm&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Fetch all users except superuser
users = User.objects.exclude(is_superuser=True).all()
user_emails = [user.email for user in users]

# try sending email
try:
    res = sm(
        subject=subject,
        html_message=message,
        from_email=EMAIL_HOST_USER,
        recipient_list=user_emails,
        fail_silently=False,
        message=None)
    print(f'Email send to {len(user_emails)} users')
except Exception:

    # retry when fail
    send_notification.retry()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;So here I created a task called `send_notification`.
`default_retry_delay` : retry after 300 seconds when fail
`max_retries` : only retry 5 more times then STOP.
Here I am also getting `subject` and `message` as arguments. This means I can pass `subject` and `message` from django admin. I will show you this later.


2. Let's go to django admin
`localhost:8080/admin`.  

**You will see new `Periodic Tasks` Menu**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3dd9pno3z8miartnckan.png)


**Let's make a `crontab` Crontab &amp;gt; Add crontab**
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p9plewa00ay3yf9tz2so.png)



**Let's create a crontab .Here I created one.  `Every Saturday @ 10:47 p.m.`**
 If you are not sure about crontab, check this out [Crontab examples] (https://crontab.guru/examples.html)
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bojci16hsrh89fnko09z.png)

**Let's create a periodic task**
Click `Periodic tasks` &amp;gt; `Add`. Create a new name of your choice. Find `send_notification` task that we have created up there
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r7mppp6d2owprmlrarnk.png)


`Schedule` &amp;gt; `Crontab Schedule` &amp;gt; Find the `crontab` you just created.
Add the `Start Datetime`
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zpac15g3tsefqgvh8csp.png)


This is where you pass the arguments `subject` and `message`
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gy2gy4z6m5gb3r8tv4t2.png)



So we are all set and ready to go.

Start django server, start rabbitmq

Start celery
`celery -A djangocelery(app name) worker --loglevel=info`

Start celery beat in different terminal
`celery -A djangocelery(app name) beat -l INFO --scheduler django_celery_beat.schedulers:DatabaseScheduler`


Let's check out the terminal of celery beat

@10:47 p.m. celery beat scheduler is sending `send_notification` task that we have created!! to celery!!
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h47zq65i4rujz2wx5or6.png)



Check celery terminal. Celery has received the task and email is sent.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mm193y1n7beyaaixsoud.png)


And I have received the email at 10:47 p.m. on Saturday with the title and content that I have set up in django admin!
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mqip5axzexn9e157q3xt.png)



###Conclusion
So `celery beat` is a `scheduler` and `celery` is the one that executes the `task`. `Database scheduler` is one of the method of celery beat where tasks and schedules are stored in database which means you can manage them in `django admin`.

&amp;lt;br/&amp;gt;
That's it for django celery beat!
The end.



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>database</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>Understanding celery and creating simple task in django</title>
      <dc:creator>Daeen Choi</dc:creator>
      <pubDate>Sat, 30 Jan 2021 14:55:11 +0000</pubDate>
      <link>https://dev.to/daeenchoi/understanding-celery-and-creating-simple-task-in-django-3gdk</link>
      <guid>https://dev.to/daeenchoi/understanding-celery-and-creating-simple-task-in-django-3gdk</guid>
      <description>&lt;h2&gt;
  
  
  Aim of this post
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Understand what is celery &lt;/li&gt;
&lt;li&gt;Create a simple task in Django project (celery)&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  What is celery?
&lt;/h4&gt;

&lt;p&gt;Celery is an &lt;code&gt;asynchronous&lt;/code&gt; processing and &lt;code&gt;scheduling&lt;/code&gt; tool in Django (not limited to Django).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;So what is asynchronous?&lt;/code&gt;&lt;br&gt;
When a client sends a request to the server, normally client cannot do anything until it receives a response from the server. That said, when request is time-consuming work, I mean more than 1 minute to handle, &lt;br&gt;
user will start clicking the refresh button couple of times or click on the back button.&lt;/p&gt;

&lt;p&gt;To prevent this situation, we process APIs asynchronously. Asynchronous processing allows clients to send requests and do other tasks immediately. When the response returns, the processing of the response continues.&lt;/p&gt;

&lt;p&gt;This asynchronous processing is done by celery.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;What about scheduling?&lt;/code&gt;&lt;br&gt;
You can make a task which runs at 8 o'clock every morning. Or you might also want to send e-mails to users every Friday at 4:00 p.m. This is possible with celery-beat.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;How does celery work?&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fswry6zpwn3b28roeg1rf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fswry6zpwn3b28roeg1rf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
The unit of work that Celery has to deal with is called a task. Producer (celery) creates a task and the task is added to the Task Queue before it is executed. The broker then forwards the task in the task queue to the appropriate worker node which is the consumer (celery) where the task is executed. Celery can be seen as a larger concept, including producer, broker, and consumer. &lt;/p&gt;
&lt;h4&gt;
  
  
  Let's create a simple task!
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Prepare a django project (any project is fine - you can just use &lt;a href="https://docs.djangoproject.com/en/3.1/intro/tutorial01/" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/3.1/intro/tutorial01/&lt;/a&gt; if you don't know where to start)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install and run rabbitmq. (I used homebrew) &lt;br&gt;
Try &lt;a href="https://www.rabbitmq.com/install-homebrew.html" rel="noopener noreferrer"&gt;https://www.rabbitmq.com/install-homebrew.html&lt;/a&gt; if you don't have rabbitmq yet.&lt;br&gt;
&lt;code&gt;brew services start rabbitmq&lt;/code&gt; to start up rabbitmq&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install celery in virtual environment&lt;br&gt;
&lt;code&gt;pip install celery&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create new celery app&lt;br&gt;
&lt;code&gt;python manage.py startapp djangocelery&lt;/code&gt; &amp;lt;- you can name your app anything. I called mine &lt;code&gt;djangocelery&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Settings and more&lt;br&gt;
5-1. create &lt;code&gt;celery.py&lt;/code&gt; &lt;code&gt;djangocelery&lt;/code&gt; app(directory) and add following code&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'betweak.settings') 
app = Celery('djangocelery') 

# You can add celery settings in settings.py starting with CELERY_ 
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks(lambda : settings.INSTALLED_APPS)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;5-2. Edit djangocelery &amp;gt; &lt;strong&gt;init&lt;/strong&gt;.py file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from .celery import app as celery_app
# celery app is automatically imported when django starts
__all__ = ['celery_app']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5-3. Edit settings.py&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSTALLED_APPS = [

   ...
   'celery'
   'djangocelery' # newly created app
]

# set CELERY settings with CELERY_{}
CELERY_BROKER_URL = amqp://guest:guest@localhost:5672/ # rabbitmq setting
CELERY_TIMEZONE = 'Asia/Seoul'
CELERY_ENABLE_UTC=False
CELERY_TASK_SERIALIZER = 'json'
CELERY_ACCEPT_CONTENT = ['json']

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6 . Migrate database&lt;br&gt;
&lt;code&gt;python mange.py migrate&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;7 . Create task&lt;/p&gt;

&lt;p&gt;Create task.py file in djangocelery and add following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from djangocelery.celery import app

@app.task(name="mod", bind=True, default_retry_delay=10, max_retries=5)
def mod(self, x, y):
    try:
        z = x % y
        print(f'{x} % {y} = {x%y}')
        return z
    except :
        mod.retry()
        print(f'Error with mod')

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;8 . Add views so we can access task with API&lt;/p&gt;

&lt;p&gt;djangocelery &amp;gt; views.py&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from django.http import HttpResponse
from rest_framework.decorators import api_view
from djangocelery.tasks import mod

@api_view(['GET'])
def get_test_add(request):
    x, y = int(request.query_params.get('x')), int(request.query_params.get('y'))
    mod.apply_async(args=(x, y), countdown=20)
    return HttpResponse(f'Success !')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;djangocelery &amp;gt; urls.py&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from django.urls import path

from djangocelery import views

urlpatterns = [
    path('mod', views.get_test_add)
]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;betweak &amp;gt; urls.py (project urls)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;urlpatterns = [
    path('celery/', include('djangocelery.urls')),
    path('admin/', admin.site.urls),
]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok so settings are ready. Let's test it out!&lt;/p&gt;

&lt;h4&gt;
  
  
  Run celery
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;celery -A djangocelery worker loglevel-info&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Run django (in another terminal)
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;python manage.py runserver&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9n3qklt5v04g7ibwra6d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9n3qklt5v04g7ibwra6d.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's check celery log to see what's happening.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe7gcbx4upcv0wlbdwq2f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fe7gcbx4upcv0wlbdwq2f.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that at 22:32:33 the task is received. Approximately 20 seconds later at 22:32:54, the task succeeded.&lt;/p&gt;

&lt;p&gt;If we see djangocelery &amp;gt; views.py again&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffrom djangocelery.tasks import mod
@api_view(['GET'])
def get_test_add(request):

    # so we get the x and y values from the url
    x, y = int(request.query_params.get('x')), int(request.query_params.get('y'))

    # Here countdown=20 means executes in 20 seconds from now 
    mod.apply_async(args=(x, y), countdown=20)
    return HttpResponse(f'Success ! ')

```



Well that was easy?

Let's try to make an error. We will pass 0 value for y. Python raises when we try to use 0 for modulo.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/jrsp78p46hagpqt0rh26.png)


Let's check the log out
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0dekbl3tza3atqtta6u8.png)

There's a lot going on there. We see there was a ZeroDivisionError, and the task retried 5 times!

djangocelery &amp;gt; task.py


```
# Here are the settings for retries!!
@app.task(name="mod", bind=True, default_retry_delay=10, max_retries=5)
def mod(self, x, y):
    try:
        z = x % y
        print(f'{x} % {y} = {x%y}')
        return z
    except :
        mod.retry()
        print(f'Error with add')

```




So that's it for getting started with celery in django :)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>python</category>
      <category>django</category>
    </item>
  </channel>
</rss>
