Marcos
Marcos

Reputation: 81

Why do I have to reload twice before my HTML gets updated in Django?

i'm working on a videogames webstore on Django, currently on the cart.

This are the basic components of the system:

Models:

class Videogame(models.Model):
  name = models.CharField(max_length=50, blank=False, unique=True)
  image = models.ImageField(upload_to='products_images/', blank=False)
  category =  models.ManyToManyField(Category)
  description = models.TextField(blank=True)
  stock = models.DecimalField(blank=True, null=True, max_digits=3, decimal_places=0, default=0)
  price = models.DecimalField(blank=False, max_digits=6, decimal_places=2, default=0.00)
  visible = models.BooleanField(blank=False, default=True)
  class Meta:
    verbose_name_plural = 'Videogames'
  def __str__(self):
        return self.name

class ItemInCart(models.Model):
  amount = models.PositiveIntegerField(default=1)
  product = models.OneToOneField(to=Videogame, on_delete=CASCADE)
  id = models.TextField(primary_key=True)
  class Meta:
    verbose_name_plural = 'Items In Cart'
  def __str__(self):
    return self.id

class VisitingClient(models.Model):
  id = models.GenericIPAddressField(primary_key=True)
  amount_of_visits = models.IntegerField(default=1)
  first_visit = models.DateTimeField(auto_now_add=True)
  last_visit = models.DateTimeField(auto_now=True)
  items_in_cart = models.ManyToManyField(ItemInCart)

  def __init__(self,*args,**kwargs):
        super(VisitingClient, self).__init__(*args, **kwargs)
        if self.amount_of_visits is None:
            self.amount_of_visits = self.amount_of_visits
            
  def __str__(self):
        return self.id

Now, in the html of my catalog section, I have this:

<div id="videogames_in_category">
  {% for videogame in videogames %}
    {% if videogame.visible is True %}
      <div class="videogame_container" style="background-image: url({{videogame.image.url}});">
        <div class="videogame_data">
          <span class="videogame_name">{{ videogame.name }}</span>
          <span class="videogame_price">${{ videogame.price }}</span>
          <div class="videogame_buttons">
            <button class="info_button" title="Información del producto"></button>
            <button class="add_to_cart_button" title="Añadir al carrito" data-assigned_product="{{ videogame.name }}"></button>
          </div>
        </div>
      </div>
    {% endif %}
  {% endfor %}
</div>

If the users touch the add to cart client, this happens in JS:

$(".add_to_cart_button").on("click", function() {
  const csrftoken = Cookies.get('csrftoken');
  let requested_item = $(this).attr("data-assigned_product");
  $.ajax({
    method: 'POST',
    headers: {'X-CSRFToken': csrftoken},
    data: {
        "result": requested_item
    },
    dataType: "json",
    success: RefreshPage()
  }).done(function(data) {
    if (data.success) {
      window.location.href = data.url;
    }
  })
});

And this is how my view looks like

def category_view(request, selected_category):
  videogames_in_category = Videogame.objects.filter(category = Category.objects.get(name=selected_category))

  client_id = request.session.get('client_id', request.META['REMOTE_ADDR'])
  if not ClientExists(client_id):
    CreateClient(client_id)
  current_client_object = VisitingClient.objects.get(pk=client_id)
  UpdateClientAmountOfVisits(current_client_object)

  context = {
    'called_category': selected_category,
    'videogames': videogames_in_category,
    'items_in_cart': current_client_object.items_in_cart.all()
  }

  requested_game_in_cart = request.POST.get('result')
  if requested_game_in_cart != None:
    asked_videogame = Videogame.objects.get(name=requested_game_in_cart)
    if ItemInCart.objects.filter(id=asked_videogame).exists():
      cart_item = ItemInCart.objects.get(id=asked_videogame)
      cart_item.amount = cart_item.amount + 1
      cart_item.save()
    else:
      cart_item = ItemInCart.objects.create(id=requested_game_in_cart, product=asked_videogame)
      current_client_object.items_in_cart.add(cart_item)
      current_client_object.save()
    return JsonResponse({
            'success': True,
            'url': '/catalog/' + selected_category + '/'
        })

Here, i basically heck for the clients existance, create it if necessary, and then wait for the AJAX POST, for then updating the client object with a new Item in Cart, and sending the success sign to the AJAX, where i proceed to reload the page so the HTML gets updated with the new item.

Apparently, I have to reload twice before the item shows up. What's going on? Why don't just one reload works? Thanks!

Upvotes: 1

Views: 385

Answers (1)

Lewis
Lewis

Reputation: 2798

RefreshPage() will call (presumably) a function to refresh the page.

You're then stating that once it has done you will refresh the page again (window.location.href = data.url;).

RefreshPage()
  }).done(function(data) {
    if (data.success) {
      window.location.href = data.url;
    }

Therefore calling two GET requests to the server and "reloading" twice.

Upvotes: 1

Related Questions