skip to Main Content

I am writing a program to retrieve data and display it in a Django template. I have a function called match_algo() that takes a long time to run. I want to initially show ‘Loading………..’ on the page, and once the function completes and returns the result, I want to display the retrieved content on the page.

This is the view I tried first:

def redirected_page(request):
    data = match_algo()
    
    context = {
        'data' : json.dumps(data),
        'test' : 'test'
    }
    
    return render(request , 'redirected_page.html' , context )

After some research, I found that WebSockets might help with this, but I’m still not sure if it’s the solution I need.

This is my consumer.py:

class LoadingConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        await self.accept()

       
        # Send "loading..." message when the connection is established
        await self.send(text_data=json.dumps({
            'message': 'loading...',
            "status" : False
        }))

        data = match_algo()

        # Send "loading completed" message after processing is done
        await self.send(text_data=json.dumps({
            'message': "loaded",
            "status" : True,
            # "matches" : data
        }))

        # Close the connection after sending the final message
        await self.close()

For testing purpose I commented this line
data = match_algo()

then added time.sleep(5).

This actually works. But when I run with match_algo after few seconds, the websockets disconnects. But the function match_algo works. Since the websocket connection is closing. I can’t get the result nor can I display it.

Is there any way to fix this? Or any better method??

redirect.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Therapist Details</title>
    <style>
        table {
        width: 100%;
        border-collapse: collapse;
        }
        th, td {
        padding: 8px;
        text-align: left;
        border-bottom: 1px solid #ddd;
        }
        th {
        background-color: #f2f2f2;
        }
        body {
            margin : 80px 150px
        }
    </style>
</head>
<body>
    <h1>Therapist Details</h1>
    <div id="therapist-table-container">
        Matching Therapist suitable for you. Please wait.
    </div>
    
    <script>
        const loadingMessage = document.getElementById('loadingMessage');
        const socket = new WebSocket('ws://' + window.location.host + '/ws/loading/');

        socket.onopen = function(event) {
            console.log('WebSocket opened with code:', event.code);
        };

        socket.onmessage = function(event) {
            const data = JSON.parse(event.data);
            console.log(data.message)
            console.log(data.matches)
            
            if (data.status) {
                const tableHTML = `
                <table>
                  <thead>
                    <tr>
                      <th>Name</th>
                      <th>Specialty</th>
                      <th>Experience</th>
                      <th>Contact</th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr>
                      <td>John Doe</td>
                      <td>Clinical Psychology</td>
                      <td>10 years</td>
                      <td>[email protected]</td>
                    </tr>
                    <tr>
                      <td>Jane Smith</td>
                      <td>Marriage and Family Therapy</td>
                      <td>8 years</td>
                      <td>[email protected]</td>
                    </tr>
                    <tr>
                      <td>Michael Johnson</td>
                      <td>Child and Adolescent Therapy</td>
                      <td>12 years</td>
                      <td>[email protected]</td>
                    </tr>
                  </tbody>
                </table>
                `;
        
                // Add the table to the DOM
                const tableContainer = document.getElementById('therapist-table-container');
                tableContainer.innerHTML = tableHTML;
              } else {
                // Hide the table if data.status is false
                const tableContainer = document.getElementById('therapist-table-container');
                tableContainer.innerHTML = 'Matching Therapist suitable for you. Please wait.';
              }
        };

        socket.onclose = function(event) {
            console.log('WebSocket closed with code:', event.code);
        };
    </script>
</body>
</html>

Thanks for your time

2

Answers


  1. Websocket is a good way.

    Javascript Websocket
    https://developer.mozilla.org/en-US/docs/Web/API/WebSocket

    Python Websocket
    https://pypi.org/project/websockets/

    Send / Recive, any data in real time without any refresh, you can use Javascript like (document.getelement…) and change html data on recive any value.

    Login or Signup to reply.
  2. You can do one of the following.

    • Use Celery for Background Tasks :- Celery is a system that implements and executes long-running tasks asynchronously and efficiently. It is compatible with Django and allows running match_algo() in the background while simultaneously notifying the client through WebSockets when the task is completed.

    • Django Channels with WebSockets: Using Django channels, you can manage WebSocket connections relatively comfortably. For instance, the page can be "busy" and display a "Loading…" text while match_algo() is being processed, then refresh when the processing is over.

    • AJAX Polling as an Alternative: Polling could be done instead of web sockets by periodically asking the server if the task has been completed using AJAX. Although it is less effective than WebSockets, it is easier to implement since it does not always need a connection open.

    • Django’s Background Tasks: In most simple cases, when managing Djangos django-background-tasks, it is provided for creating background processes without the stickiness of fully fledged application Queues like Celery

    You can read more on these methods to decide the best method for your usecase.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search