Почему в Django я должен дважды перезагрузиться, прежде чем мой HTML обновится?
Я работаю над веб-магазином видеоигр на Django, в настоящее время над корзиной.
Вот основные компоненты системы:
Модель Видеоигры, содержащая основную информацию о Видеоигре (название, изображение, цена, акции и т.д.)
Модель Item in Cart, содержащая целочисленное поле (количество) и поле видеоигр "один к одному". Идея заключается в том, чтобы иметь модель с количеством раз, когда видеоигра была добавлена в корзину определенным клиентом
.Модель Посетивший клиент, содержащая IP посетителя в качестве ID и поле Many to Many модели Item in Cart
.
Модели:
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
Теперь, в html разделе моего каталога, у меня есть следующее:
<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>
Если пользователи касаются клиента добавления в корзину, то в 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;
}
})
});
А вот так выглядит мой вид
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 + '/'
})
Здесь я в основном проверяю существование клиента, создаю его, если необходимо, и затем жду AJAX POST, чтобы затем обновить объект клиента с новым товаром в корзине и отправить знак успеха в AJAX, где я продолжаю перезагружать страницу, чтобы HTML был обновлен новым товаром.
Очевидно, мне приходится дважды перезагружаться, прежде чем элемент появится. Что происходит? Почему не работает только одна перезагрузка? Спасибо!
RefreshPage()
вызовет (предположительно) функцию для обновления страницы.
Вы утверждаете, что как только это произойдет done
, вы снова обновите страницу (window.location.href = data.url;
).
RefreshPage()
}).done(function(data) {
if (data.success) {
window.location.href = data.url;
}
Таким образом, вызывая два GET-запроса к серверу и "перезагружаясь" дважды.