Estoy tratando de agregar productos a mi cesta sin actualizar la página y tengo
direcciones URL:
app_name = 'basket' urlpatterns = [ path('', views.BasketView.as_view(), name='summary'), path('/add', views.BasketView.post, name='basket_add'), ]puntos de vista:
class BasketView(generic.list.ListView): template_name = 'basket/basket.html' model = Category def post(self, request, *args, **kwargs): data = request.POST print(data) return 'something'html (+JS):
... <button onclick="basket_add(this)" id="{{ item.id }}"></button> ... <script> function send_productId(id){ var request = new XMLHttpRequest(); request.open('POST', '{% url 'basket:basket_add' %}', true); request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); const data = { id: id, csrfmiddlewaretoken:'{{ csrf_token }}', action: "POST", }; request.send(data); }; function basket_add(obj){ send_productId(obj.id); }; </script>después de presionar el botón me sale este error
Prohibido (falta el token CSRF): /basket/add
Entonces, ¿cómo puedo al menos imprimir datos correctamente o necesito hacerlo de otra manera?
Aquí está la solución a su error. Puede agregar csrf_exempt a su método de post . Esto le permitirá enviar el formulario sin csrf token .
from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator @method_decorator(csrf_exempt, name='dispatch') class BasketView(generic.list.ListView): template_name = "basket/basket.html" model = Category def post(self, request, *args, **kwargs): data = request.POST print(data) return "something" PD: heredar de CreateView o simplemente de la clase View si lo está utilizando para crear un nuevo objeto. Y en urls.py usa tu ruta algo como esto
path("/add", BasketCreateView.as_view(), name='basket_add') en lugar de su ruta actual.
Y eche un vistazo a javascript fetch para hacer llamadas al servidor. Te hará la vida mucho más fácil.