Ссылка на локальную переменную 'X' перед присвоением в представлениях Django
Я работаю с Django и пытаюсь создать две формы на одной странице, с чем у меня возникают трудности. Это для простого интернет-магазина, которому нужна секция доставки и оплаты на странице оформления заказа. Я просто следую учебнику youtube и пробую некоторые вещи.
Я хотел бы узнать, почему я получаю ошибку "local variable 'street_address' referenced before assignment", исходящую из строки 131 в views. Если есть какие-либо другие ошибки, пожалуйста, дайте мне знать, так как я не совсем понимаю, как разместить две формы на одной странице. Единственный способ сделать это - сделать отдельную страницу для оплаты?
VIEWS.PY - CheckoutView Class
def get(self, *args, **kwargs):
form = AddressForm()
form_2 = PaymentForm()
order_items = OrderItem.objects.all()
context = {
'form': form,
'form_2': form_2,
'items': order_items
}
return render(self.request,"Order_Management/checkout.html", context)
def post(self, *args, **kwargs):
form = AddressForm(self.request.POST or None)
form_2 = PaymentForm(self.request.POST or None)
# order, created = Order.objects.get_or_create(customer=customer, complete=False)
# order = Order.objects.get(user=self.request.user, ordered=False)
if all([form.is_valid(), form_2.is_valid()]):
street_address = form.cleaned_data.get('street_address')
city = form.cleaned_data.get('city')
postcode = form.cleaned_data.get('postcode')
country = form.cleaned_data.get('country')
state = form.cleaned_data.get('state')
shipping_method = form.cleaned_data.get('shipping_method')
card_num = form.cleaned_data.get('card_num')
cvc = form.cleaned_data.get('cvc')
exp_date = form.cleaned_data.get('exp_date')
address = Shipping(
user=self.request.user,
street_address=street_address,
city=city,
postcode=postcode,
country=country,
state=state,
shipping_method=shipping_method
)
card_details = Payment(
user=self.request.user,
card_num=card_num,
cvc=cvc,
exp_date=exp_date
)
address.save()
card_details.save()
return render(self.request,"Order_Management/checkout.html")'''
MODELS.PY
class Payment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
order = models.ForeignKey(Order, on_delete=models.CASCADE)
card_num = models.IntegerField(null=True)
cvc = models.IntegerField(null=True)
exp_date = models.CharField(max_length=8, null=True)
amount = models.DecimalField(max_digits=7, decimal_places=3)
def __str__(self):
return self.amount
HTML
<form class="card-body" method="POST">
{% csrf_token %}
{% if form_2 %}
{% endif %}
<div id="payment-info">
<p>Payment Information:</p>
<div class="md-form mb-5">
<input type="text" name="card_num" id="card_num" class="form-control" placeholder="Card Number..." required>
<input type="text" name="cvc" id="cvc" class="form-control" placeholder="CVC..." required>
<input type="text" name="exp_date" id="exp_date" class="form-control" placeholder="Expirey Date..." required>
</div>
</div>
<hr class="mb-4">
<button class="btn btn-primary btn-lg btn-block" type="submit">Place Order</button>
</form>
</div>
Проблема в том, что вы проверяете, являются ли формы действительными... и если они действительны, вы получаете значения из них и присваиваете их переменным.
Но часть вашего кода, где вы конструируете модели Shipping и Payment и сохраняете их, выполняется каждый раз, она не отделена внутри блока, где вы проверяли валидность форм.
В результате, если одна из форм недействительна, ваш код все равно попытается построить модели, и не сможет этого сделать, потому что вы не присвоили переменные из форм.
Так что вам нужно сделать отступ от всего этого кода, чтобы он был под вашей проверкой достоверности.
if all([form.is_valid(), form_2.is_valid()]):
street_address = form.cleaned_data.get('street_address')
city = form.cleaned_data.get('city')
postcode = form.cleaned_data.get('postcode')
country = form.cleaned_data.get('country')
state = form.cleaned_data.get('state')
shipping_method = form.cleaned_data.get('shipping_method')
card_num = form.cleaned_data.get('card_num')
cvc = form.cleaned_data.get('cvc')
exp_date = form.cleaned_data.get('exp_date')
address = Shipping(
user=self.request.user,
street_address=street_address,
city=city,
postcode=postcode,
country=country,
state=state,
shipping_method=shipping_method
)
card_details = Payment(
user=self.request.user,
card_num=card_num,
cvc=cvc,
exp_date=exp_date
)
address.save()
card_details.save()
return render(self.request,"Order_Management/checkout.html")