Django - Как вызвать функцию с аргументами внутри шаблона

У меня есть следующее представление, основанное на функциях:

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')

Я хочу разместить 3 кнопки на моем front-end, которые вызывают одну и ту же функцию с разными аргументами каждый раз, например, одна кнопка get_emails(FU_HOST, FU_USERNAME, FU_PASSWORD), другая get_emails(USV_HOST, USV_USERNAME, USV_PASSWORD).

Как этого можно добиться в Django? Мои учетные данные хранятся в .env файле.

Подобное не достигается путем размещения этой функции в шаблоне фронтенда, вам нужно перенаправить пользователя на представление, содержащее эту функцию, и извлечь эти значения из запроса пользователя, потому что, как вы видите, у вас есть методы, которые бьют по вашей базе данных, а это не то, чего вы можете достичь с фронтенда, и это не безопасно, если бы это было возможно.

Из контекста я могу понять, что аргументы, передаваемые в вашу функцию, должны быть безопасными.

Итак, используйте форму POST, например, такую:

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')

В шаблоне сделайте запрос на пост, указав хост, имя пользователя и пароль следующим образом.

<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>

Если метод отправки формы не работает, вы можете использовать javascript и ajax. Для этого сценария, если метод отправки формы не работает для вас, вы можете использовать javascript и ajax.

Добавьте следующие коды в ваш html-код, чтобы использовать метод javascript.

<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>

Обновите функцию python следующим образом.

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')

Надеюсь, это поможет.

Вернуться на верх