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.