0

I am in a quite strange situation. I have this form:

<form method="post" id="preventivo-form">
        {% csrf_token %}
        <input type="hidden" name="product_id" value="{{servizio.id_prodotto_stripe}}">
        <input type="hidden" name="uuid" value="{{pratica.identificativo}}">
        <input type="submit" value="Paga">
</form>

Variables inside hidden inputs displays the correct values. I need to pass these variables to another view, so I've written this js:

document.addEventListener('DOMContentLoaded', function () {

    const body = document.body;

    this.body.addEventListener('submit', function (event) {
        
        if (event.target.id === 'preventivo-form') {
            event.preventDefault();

            const form = event.target;
            const token = form.querySelector('input[name="csrfmiddlewaretoken"]').value;

            const xhr = new XMLHttpRequest();
            const action = '/recupero-credito/elements/';
            xhr.open('POST', action, true);
            // xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.setRequestHeader('X-CSRFToken', token);

            const formData = new FormData(form);
            formData.append('product_id', form.querySelector('input[name="product_id"]').value);
            formData.append('uuid', form.querySelector('input[name="uuid"]').value);

            xhr.onload = function () {
                if (xhr.status >= 200 && xhr.status < 400) {
                    console.log('done');
                    window.location.href = '/recupero-credito/elements/';
                } else {
                    alert('Server error');
                }
            };

            xhr.onerror = function () {
                alert('Request failed');
            };

            xhr.send(formData);
        }
    })


})

This is the view that receives these data:

def stripe_elements(request):
    price = decimal.Decimal(stripe.Price.retrieve(
        'price_XXXXXXXX').unit_amount_decimal) / 100
    pratica = PraticaRecuperoCredito.objects.get(
        utente=request.user, temporaneo=True)
    uuid = None
    product_id = None
    context = {}
    context['pratica'] = pratica
    if request.method == 'POST':
        uuid = request.POST.get('uuid')
        product_id = request.POST.get('product_id')
        print('uuid:', uuid)
        print('product_id:', product_id)
        pratica = PraticaRecuperoCredito.objects.get(
            utente=request.user, temporaneo=True, identificativo=uuid)
        print(pratica.identificativo)
        servizio = Servizio.objects.get(id_prodotto_stripe=product_id)
        form = CreditorePfForm(request.POST, instance=pratica)
        if form.is_valid():
            form.save()
        context['price'] = price

        context['servizio'] = servizio
        context['form'] = form

    else:
        form = CreditorePfForm()
        context['price'] = price
        context['form'] = form
    context['uuid'] = uuid
    context['product_id'] = product_id
    return render(request, 'recupero_credito/elements.html', context)

this view has this url:

from django.urls import path
from . import views

app_name = 'recupero_credito'

urlpatterns = [
    #others urls
    path('elements/',
         views.stripe_elements, name='stripe_element'),
    #others urls
]

Note that the urls.py of this app is included in this way:

urlpatterns = [
    #others urls
    path('recupero-credito/', include('recupero_credito.urls')),

]

elements.html has the following code:

<form id="payment-form" method="post">
                    <input type="hidden" id="csfr_token" name="csrfmiddlewaretoken" value="{{csrf_token}}">
                    <input type="hidden" name="product_id" value="{{product_id}}">
                    <input type="hidden" name="uuid" value="{{uuid}}">
                    <h3>Dettagli per il pagamento</h3>
                    <p>product_id: {{product_id}}</p>
                    <p>uuid: {{uuid}}</p>
                    <p>price: {{price}}</p>
                    <div class="row">
                        {% for field in form %}
                        <div class="col-lg-6 col-md-6 col-sm-12 form-floating mb-3 mt-3">
                            {{field}}
                            <label class="label-container mb-2" for="{{field.auto_id}}">{{field.label}}</label>
                            <div id="{{field.name}}_error" class="error-message"></div>
                        </div>

                        {% endfor %}
                    </div>
                    <div id="card-element">
                        <!-- Elements will create form elements here -->
                    </div>
                    <button id="submit-button" type="submit" class="btn-black-outline mt-3">Procedi al
                        pagamento</button>
                </form>

The strange thing here is that: the print statement inside stripe_elements view prints the values expected (so the hidden input's values are available in the view); instead, in the template both the values associated to the variables uuid and product_id are None.

Another thing I don't understand is: if I move 'pratica' outside request method == 'POST' I can use the object's properties in elements.html, while if I move it inside I can't. I mean, nothing is shown from pratica variable.

I know I am missing some crucial Django's concept here.

Andrea
  • 61
  • 6

0 Answers0