Home > Mobile >  Django - How to call a function with arguments inside a template
Django - How to call a function with arguments inside a template

Time:11-30

I have the following function-based view:

def get_emails(request, HOST, USERNAME, PASSWORD):
    context = {
        'FU_HOST': settings.FU_HOST,
        'FU_USERNAME': settings.FU_USERNAME,
        'FU_PASSWORD': settings.FU_PASSWORD,
        'FV_HOST': settings.FV_HOST,
        'FV_USERNAME': settings.FV_USERNAME,
        'FV_PASSWORD': settings.FV_PASSWORD,
        'USV_HOST': settings.USV_HOST,
        'USV_USERNAME': settings.USV_USERNAME,
        'USV_PASSWORD': settings.USV_PASSWORD,
    }
    m = imaplib.IMAP4_SSL(HOST, 993)
    m.login(USERNAME, PASSWORD)
    m.select('INBOX')
    result, data = m.uid('search', None, "ALL")
    if result == 'OK':
        for num in data[0].split():
            result, data = m.uid('fetch', num, '(RFC822)')
            if result == 'OK':
                email_message_raw = email.message_from_bytes(data[0][1])
                email_from = str(make_header(decode_header(email_message_raw['From'])))
                email_addr = email_from.replace('<', '>').split('>')
                if len(email_addr) > 1:
                    new_entry = EmailMarketing(email_address=email_addr[1], mail_server='X')
                    new_entry.save()
                else:
                    new_entry = EmailMarketing(email_address=email_addr[0], mail_server='X')
                    new_entry.save()
    m.close()
    m.logout()

    messages.success(request, f'Subscribers list sychronized successfully.')
    return redirect('subscribers')

I'd like to place 3 buttons on my front-end that call this same function with different arguments each time, for example one button get_emails(FU_HOST, FU_USERNAME, FU_PASSWORD), the other button get_emails(USV_HOST, USV_USERNAME, USV_PASSWORD).

How can one achieve this in Django? My credentials are stored in .env file.

CodePudding user response:

Something like this is not achieved by placing that function on your frontend template, what you need to be doing is to redirect the user to a view that contains that function and by extracting these values from the users request, because as you can see you've got methods that are hitting your Database, which isn't something you can achieve from the frontend nor is it safe if it were possible.

CodePudding user response:

From the context I can understand that the arguments that are passed to your function must be secure.

So, go with a POST form like this:

def get_emails(request):
    context = {
        'FU_HOST': settings.FU_HOST,
        'FU_USERNAME': settings.FU_USERNAME,
        'FU_PASSWORD': settings.FU_PASSWORD,
        'FV_HOST': settings.FV_HOST,
        'FV_USERNAME': settings.FV_USERNAME,
        'FV_PASSWORD': settings.FV_PASSWORD,
        'USV_HOST': settings.USV_HOST,
        'USV_USERNAME': settings.USV_USERNAME,
        'USV_PASSWORD': settings.USV_PASSWORD,
    }

    if request.method == "POST":
        HOST = request.POST["HOST"]
        USERNAME = request.POST["USERNAME"]
        PASSWORD = request.POST["PASSWORD"]

        m = imaplib.IMAP4_SSL(HOST, 993)
        m.login(USERNAME, PASSWORD)
        m.select('INBOX')
        result, data = m.uid('search', None, "ALL")
        if result == 'OK':
            for num in data[0].split():
                result, data = m.uid('fetch', num, '(RFC822)')
                if result == 'OK':
                    email_message_raw = email.message_from_bytes(data[0][1])
                    email_from = str(make_header(decode_header(email_message_raw['From'])))
                    email_addr = email_from.replace('<', '>').split('>')
                    if len(email_addr) > 1:
                        new_entry = EmailMarketing(email_address=email_addr[1], mail_server='X')
                        new_entry.save()
                    else:
                        new_entry = EmailMarketing(email_address=email_addr[0], mail_server='X')
                        new_entry.save()
        m.close()
        m.logout()

        messages.success(request, f'Subscribers list sychronized successfully.')
        return redirect('subscribers')

In the template, make a post request, given the host, username and password like this.

<form action="{% url 'name-of-your-view' %}" method="POST">
<input type="text" name="HOST">
<input type="text" name="USERNAME">
<input type="text" name="PASSWORD">
<input type="submit">
</form>

CodePudding user response:

For this scenario, if the form post method is not working for you, you can use javascript and ajax.

Add the following codes to your html code to use the javascript method.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script>
    function post(_host,_username,_password){
        $.ajax({
            url: '{% url "url-name"%}',
            type: 'POST',
            data: { 
                csrfmiddlewaretoken: "{{ csrf_token }}",
                host: _host,
                username = _username,
                password = _password
            },
            success: function (res) {
                console.log(res);
            }
        });
    }
</script>

Update the python function as follows.

def get_emails(request):
    HOST = request.POST.get('host')
    USERNAME = request.POST.get('username')
    PASSWORD = request.POST.get('password')
    context = {
        'FU_HOST': settings.FU_HOST,
        'FU_USERNAME': settings.FU_USERNAME,
        'FU_PASSWORD': settings.FU_PASSWORD,
        'FV_HOST': settings.FV_HOST,
        'FV_USERNAME': settings.FV_USERNAME,
        'FV_PASSWORD': settings.FV_PASSWORD,
        'USV_HOST': settings.USV_HOST,
        'USV_USERNAME': settings.USV_USERNAME,
        'USV_PASSWORD': settings.USV_PASSWORD,
    }
    m = imaplib.IMAP4_SSL(HOST, 993)
    m.login(USERNAME, PASSWORD)
    m.select('INBOX')
    result, data = m.uid('search', None, "ALL")
    if result == 'OK':
        for num in data[0].split():
            result, data = m.uid('fetch', num, '(RFC822)')
            if result == 'OK':
                email_message_raw = email.message_from_bytes(data[0][1])
                email_from = str(make_header(decode_header(email_message_raw['From'])))
                email_addr = email_from.replace('<', '>').split('>')
                if len(email_addr) > 1:
                    new_entry = EmailMarketing(email_address=email_addr[1], mail_server='X')
                    new_entry.save()
                else:
                    new_entry = EmailMarketing(email_address=email_addr[0], mail_server='X')
                    new_entry.save()
    m.close()
    m.logout()

    messages.success(request, f'Subscribers list sychronized successfully.')
    return redirect('subscribers')

I hope it helps.

  • Related