What is the best practice of handling buttons in Djnago?

I am not sure about the best practice on generating a high amount of buttons, that will connect with Django backend, after they are clicked.

I am currently making sample online store in Django as my first project, so I can learn the framework.

Each product on the page is going to have a button to add the product to the cart of a logged user.

Should I make every button as a form, or handle the buttons with JS and fetch API. I did not fail to notice, Django heavily relies on forms as a default way to get user input, but making a so many generated forms on one page (the products are going to be a list) just doesn't feels right

I was thinking of the solution like this:

document.querySelectorAll('.add_product').forEach(e => {
    e.addEventListener('click', e =>
    // POST request (with crsf cookie and all)
    // redirecting the user, depending on the output
    )
})

Just get all buttons, get data-pk from <button>, and send it with the JS Fetch API as POST request to Django endpoint The thing I don't like about it is, I see potential CORS Issues, and I do not know if this is the right thing to to, to just bypass CORS whenever you feel like it is convenient (security is not one of my strengths. One of the reasons to use Django).

Second problem I see with my approach is the JS handeled redirect just feels messy to me when 90% of this is handled by Django's HttpResponses.

If someone finds it helpful, this is how I am sending product data to JS (items variable is the serialised QuerySet from Django's default SQLite3 Database) I am doing it this way, instead of the regular SSR template, because I am planning on adding product filters, and I don't want to refresh the page when someone changes the filter or the category

let data = {{items | safe}}; // THIS ONE LINE IS IN THE <script> TAG IN THE TEMPLATE
data.forEach(e => {
    output +=
        `<div class="product">${e.fields.item_name}>
        <button  data-pk="${e.pk}" class="add_product">
            add to cart
        </button>
    </div>`
});

Depends on how your models are set, but you don´t need a form for each product to be displayed and then added to the cart, you can add a function to your products model like this:

def add_to_cart_url(self):
        return reverse("add-to-cart", kwargs={"slug": self.slug})

that calls a function that adds the product to your 'order items' model, if you have your architecture like that.

I suggest that you take a look to this video, the part where it adds and remove items to the cart: https://www.youtube.com/watch?v=z4USlooVXG0

Back to Top