run two views at the same time

Question:

So as the title says, im trying to run two views at the same time. Or at least, that is what i think i have to do. I have system that lets user like the model and if model like count is bigger than 3, the view should be redirected to a view that sends email message to client. I dont want to put email message code in the same view as "like" view, as the like works same as like button on facebook: it has to respond fast back to the user. Also i want the like_exam view to be finished in any case, if counter < 3 or not. SO what i have now is:

def like_exam(request, letnik_id, classes_id, subject_id):
    exam_id = request.GET.get('exam')
    exam = get_object_or_404(Exam, id=exam_id)
    counter = exam.exam_likes.count()
    user = request.user
    if user in exam.exam_likes.all():
        exam.exam_likes.remove(user)
        return JsonResponse({"like": "unliked"})
    else:
        exam.exam_likes.add(user)
        if counter < 3:
           html = likes_email(exam)
           return HttpResponse(html)
        # i want the json to be posted in any case:
       return JsonResponse({"like": "liked"})

def likes_email(exam):
   ....sends email...
Asked By: zzbil

||

Answers:

There’s no way to run two views at the same time. And this isn’t what you want to do anyway, since the “likes_email” function doesn’t return a response to the user, which is part of the contract of a view.

The pattern for running time-consuming operations is to farm them out to a separate process, usually with a task queue. The best way to manage these in Django is by using Celery.

Answered By: Daniel Roseman

I don’t know that this below is what you want using threads:

# "views.py"

import time
from threading import Thread
from django.http import HttpResponse

def test1():
    for _ in range(3):
        print("Test1")
        time.sleep(1)
    
def test2():
    for _ in range(3):
        print("Test2")
        time.sleep(1)

def test(request):
    thread1 = Thread(target=test1)
    thread2 = Thread(target=test2)
    thread1.start()
    thread2.start()
    thread1.join()
    thread2.join()

    return HttpResponse("Test")

The result below on console:

Test1
Test2
Test1
Test2
Test1
Test2

Again, I don’t know that this below is what you want using asyncio:

import asyncio
from django.http import HttpResponse

async def test1():
    for _ in range(3):
        print("Test1")
        await asyncio.sleep(1)

async def test2():
    for _ in range(3):
        print("Test2")
        await asyncio.sleep(1)

async def call_tests(request):
    loop = asyncio.get_running_loop()
    loop.create_task(test1())
    await loop.create_task(test2())

    return HttpResponse("Test")

The result below on console:

Test1
Test2
Test1
Test2
Test1
Test2
Answered By: Kai – Kazuya Ito