Call and process confirmation popup from a service

Hello!

In my Django project, the business logic of each application is hosted at the service level of that application. For example, in cmp_users, the service file is responsible for managing the user model. views only perform the function of working with templates.
I have a basic template with a form and select type fields on it. When any field is changed, the script sends an AJAX request to views. views accepts this request and passes the data to a service function that uses it to write to the DB.

templateviews servicemodel

Now I need to make a function to call the Confirmation popup from service to confirm any action, receive a response from the window and process it. I already have a universal confirmation popup template, so I need a mechanism for calling it from the service and get response without interrupting the transaction.

<div class="modal fade" id="confirmation-modal" tabindex="-1" role="dialog" aria-labelledby="confirmationModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="modal-title">Confirm action</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                <p id="modal-message">Are you sure you want to continue?</p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                <button type="button" class="btn btn-primary" id="confirm-button">Ok</button>
            </div>
        </div>
    </div>
</div>

One of the implementation options was to send a response to template with a confirmation modal call. Clicking the confirm-button on it would again send an AJAX request to views with confirmation information. Then this information would be sent back to the service, which checked whether the confirmation was passed or not. However, even with one confirmation, it looks bad, and the service may need several checks at once.

Another attempt was to use a generator in the service. This allowed the confirmation window to be called without interrupting the service function.

def some_view(response):
     my_gen = service.get_generator(user)
     response = next(my_gen)
     service.save_generator(user, my_gen)
     return JsonResponse(response)


def some_generator():
     yield {'success': False,
           'confirmation_dialog': {
               'show': True,
               'title': "Test 1",
               'message': "Test 1"
           }
           }
      edit_some_model()
      yield {'success': False,
           'confirmation_dialog': {
               'show': True,
               'title': "Test 2",
               'message': "Test 2"
           }
           }
      edit_another_model()
      yield {'success': False,
           'confirmation_dialog': {
               'show': True,
               'title': "Test 3",
               'message': "Test 3"
           }
           }
commit_changes()
yield {'success': True}

However, this would interrupt the transaction in the view. Also, when calling other functions of the service that may also require confirmation, the logic of this generator is disrupted

So I need to create a universal mechanism that would allow calling a confirmation window from a service without interrupting the transaction. Here’s an example of how I would like this to be implemented:

views

import some_service as service

def some_view(request):
     result1 = service.some_service_func()
     result2 = service.another_service_func()
     if result1 and result2:
           return JsonResponce('success')
     else:
           return JsonResponce('error')
service

from cmp_modals import ConfirmDialog

def some_service_func():
''' ConfirmDialog get title and message, return bool (Confirmed or Canceled) '''
     if not ConfirmDialog(title="title", message="message"):
          return service_when_first_confirm_rejected()

     if some_condition:
          if ConfirmDialog(title="another_title", message="another_message")
               return service_when_second_confirmed()
          else:
               return service_when_second_rejected()
          

def service_when_first_confirm_rejected():
     if ConfirmDialog(title="title_when_rejected", message="message_when_rejected")
          return False
     else:
          return some_another_service_func()


def service_when_second_confirmed():
     '''some business logic, such as deleting an object from a database'''
     return True

An approximate version of what I want to get:

There can be several Dialog Confirm in one function, as the number of service functions called.

I found similar functionality in MS Business Central. I need a similar way to confirm actions

Thank You!

Welcome @LeonidSerebrennikov !

The HTTP protocol itself does not support this.

To do something like this is going to require a websocket, allowing you to exchange messages bidirectionally outside the context of a view.

This actually sounds like a valid approach to achieve your goal. What was wrong with this? Another approach would be to do some kind of polling from the confirmation dialogue box to get the results of downstream actions.

Pushing information from the downstream services to the confirmation dialogue would need something like a websocket.