1

I have some kind of online store. I need it to work so that after clicking on the buy button, which is located on the product page, the user is redirected to a page with a checkout form that contains the fields: phone number, mail and the product itself.

URLS.PY

from django.urls import path
from first.views import productsHTML, productHTML, products_category, product_buy

urlpatterns = [
    path("productsHTML/<str:uuid>/buy", product_buy, name = "product_buy"),
    path("products_category/<str:id_category>", products_category, name = "products_category"),
    path("productsHTML/<str:uuid>", productHTML, name = "productHTML"),
    path("productsHTML/", productsHTML, name = "productsHTML"),

]

FORMS.PY

class OrderForm(forms.ModelForm):
    class Meta:
        model = Order
        fields = ['email', 'phone_number']
        widgets = {
            'email': forms.EmailInput(),
            'phone_number': forms.TextInput(),
        }

VIEWS.PY

def product_buy(request, uuid):
    if request.method == 'GET':
        product = Product.objects.get(id=uuid)
        form = OrderForm()
        return render(request, 'product_buy.html', {'product': product, 'form': form})

    if request.method == 'POST':
        try:
            if form.is_valid():
                product = Product.objects.get(id=uuid)
                email = form.cleaned_data['email']
                phone_number = form.cleaned_data['phone_number']
                order = Order.objects.create(email=email, product=product,phone_number=phone_number)
                return redirect('productsHTML')
        except:
            
            return render(request, 'productHTML.html', uuid = uuid)

I use a construction try except so that in case of creating an order, the user is redirected to the page with all the products, and in case of failure: to the page of the product that he wanted to buy.

PRODUCT_BUY.HTML

{% extends 'products.html' %}
{% block title %}Оформление заказа{% endblock %}
{% block content %}
    <h1>Оформление заказа</h1>
    <form method="post" action = 'product_buy'>
        {% csrf_token %}
        {{ form.as_p }}
        <input type="Submit" name="submit" value="Купить"/>
    </form>
{% endblock %}

MODELS.PY

class Order(models.Model):

    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    email = models.EmailField(verbose_name='почта', null=True)
    phone_number = models.CharField(max_length=20, verbose_name='номер телефона')

The form seems to be displayed, but after submitting, the order is not added to the database.

I also noticed that the button is displayed as "Поиск", but I wrote value="Купить". And the form is displayed in a line, but I wrote {{ form.as_p }}. Attached a photo below.

I will be glad for any help! If you need more information, I'm ready to provide. Thank you.

image 1: https://i.stack.imgur.com/0inNm.png

dostogircse171
  • 1,006
  • 3
  • 13
  • 21

1 Answers1

1

I believe when you submit the form you are getting a 404 page displaying no url matches found. This is because you are trying to use the reverse resolution of urls in Django but you haven't used jinja tags in the url name.

{% extends 'products.html' %}
{% block title %}Оформление заказа{% endblock %}
{% block content %}
    <h1>Оформление заказа</h1>
    <form method="post" action = "{% url 'product_buy' <uuid_param_here> %}">
        {% csrf_token %}
        {{ form.as_p }}
        <input type="Submit" name="submit" value="Купить"/>
    </form>
{% endblock %}

uuid_param_here => is the param that you need to send in the request url.

{% url 'product_buy' someproduct %} is equivalent to productsHTML/someproduct/buy

Here's [a link] https://stackoverflow.com/a/42441122/10669512! to a similar problem. Please do check.

Also, your views seems incorrect. Since you are using try/except, the exceptions are not properly handled. You have not defined form variable inside post condition

if request.method == 'POST': # If the form has been submitted...
    form = OrderForm(request.POST) # A form bound to the POST data
    if form.is_valid():
        product = Product.objects.get(id=uuid)
        email = form.cleaned_data['email']
        phone_number = form.cleaned_data['phone_number']
        order = Order.objects.create(email=email, product=product,phone_number=phone_number)
        return redirect('productsHTML')

Check this for more clarification [a link] Django form is_valid() fails

Sanjay Shahi
  • 124
  • 1
  • 6