Farid Darabi
Farid Darabi

Reputation: 99

How can I define a function in django so that stays active in background?

How can I define a function that stays active in the background?

For example, I want to press a button in the admin panel and then, Django starts updating all of the movies in the database using IMDB information.

If there are too many movies in the database, It can take too long for Django to update them. So I want the process of updating to stay active in the background and don't stop if I close the web browser.

1) How is this possible?

2) Can I add a progress bar to see how many movies are updated so far?

Upvotes: 0

Views: 236

Answers (1)

Mukul Kumar
Mukul Kumar

Reputation: 2093

First Way:- You can start a thread on the click of button

import threading

# define your function to start updating the data through thread

def update_data(data):
    ....
    ....


# On the click of button, start thread

try:
    your_thread = threading.Thread(
        target=update_data,
        args=(data)
    )
    your_thread.start()
except Exception as ex:
    print("The exception is {}".format(ex))



Second Way:- You can configure celery and start celery task on the click of button

1. Install Celery

pip install Celery

2. Installing RabbitMQ

apt-get install -y erlang

apt-get install rabbitmq-server

3. Enable and start the RabbitMQ service

systemctl enable rabbitmq-server

systemctl start rabbitmq-server

4. Check the status of rabbitmq server

systemctl status rabbitmq-server

5. Add the CELERY_BROKER_URL configuration to the settings.py file

settings.py

CELERY_BROKER_URL = 'amqp://localhost'

6. Alongside with the settings.py and urls.py files, Create a new file named celery.py

celery.py

import os
from celery import Celery

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'projectname,.settings')

app = Celery('projectname')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()

7. Edit the __init__.py file in the project root

__init__.py

from .celery import app as celery_app
__all__ = ['celery_app']
8. create tasks.py inside any django app

tasks.py

import string

from django.contrib.auth.models import User
from django.utils.crypto import get_random_string

from celery import shared_task

@shared_task
def create_random_user_accounts(total):
    for i in range(total):
        username = 'user_{}'.format(get_random_string(10, string.ascii_letters))
        email = '{}@abc.com'.format(username)
        password = get_random_string(50)
        User.objects.create_user(username=username, email=email, password=password)
    return '{} random users created with success!'.format(total)
9. create forms.py inside that app

forms.py

from django import forms
from django.core.validators import MinValueValidator, MaxValueValidator

class GenerateRandomUserForm(forms.Form):
    total = forms.IntegerField(
        validators=[
            MinValueValidator(50),
            MaxValueValidator(500)
        ]
    )
10. Views in the same app

views.py

from django.contrib.auth.models import User
from django.contrib import messages
from django.views.generic.edit import FormView
from django.shortcuts import redirect

from .forms import GenerateRandomUserForm
from .tasks import create_random_user_accounts

class GenerateRandomUserView(FormView):
    template_name = 'generate_random_users.html'
    form_class = GenerateRandomUserForm

    def form_valid(self, form):
        total = form.cleaned_data.get('total')
        create_random_user_accounts.delay(total)
        messages.success(self.request, 'We are generating your random users! Wait a moment and refresh this page.')
        return redirect('users_list')
11. now in the template

generate_random_users.html

<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type=submit value="Submit" />
</form>

{% if messages %}
    {% for message in messages %}
        {{ message }}
    {% endfor %}
{% endif %}
12. start the work process

celery -A projectname worker -l info

Upvotes: 3

Related Questions