Francisco Ghelfi
Francisco Ghelfi

Reputation: 962

Django csrf_token works in one form but not in other

I have a page with two lists: for tasks (tareas) and sales (ventas). When you click their links each one opens it´s own modal and retrieves the info with AJAX.

One works with no problem (tareas). The other one gives me a csrf_token error.

I thought maybe it was a problenm of using two tokens in the same template, but I´m doing it in other templates with no problem.

And if I completely remove the tareas part, the ventas one still get´s the same error.

Venta form call

<form name="ventas_form" action="#" id="form_venta_{{operacion.comprobante}}" method="POST">
    {% csrf_token %}
    <input name="id" id="venta_id_submit" type="text" value="{{operacion.comprobante}}" hidden="true"/>
    <a style="padding-left: 1rem;" href="" id="{{operacion.comprobante}}" class="show_venta" data-toggle="modal" >{{operacion.comprobante}}</a>
</form>

Tarea form call

<form name="form" action="#" id="form_tarea_{{tarea.id}}" method="POST">
    {% csrf_token %}
    <input name="id" id="tarea_id_submit" type="text" value="{{tarea.id}}" hidden="true"/>
    <a style="padding-left: 1rem;" href="" id="{{tarea.id}}" class="show_tarea" data-toggle="modal" >{{ tarea.titulo }}</a>
</form>

Venta Ajax

<script>
   $(function(){
        $('.show_venta').on('click', function (e) {
            e.preventDefault();
            let venta_id = $(this).attr('id');

            $.ajax({
                url:'/catalog/ventas-detail/',
                type:'POST',
                data: $('#form_venta_'+venta_id).serialize(),
                success:function(response){
                    console.log(response);
                    $('.show_venta').trigger("reset");
                    openModalVentas(response);
                },
                error:function(){
                    console.log('something went wrong here');
                },
            });
        });
    });

    function openModalVentas(venta_data){
        $('#fecha').text(venta_data.venta.fecha);
        $('#comprobante').text(venta_data.venta.comprobante);
        $('#cliente').text(venta_data.venta.cliente);
        $('#vendedor').text(venta_data.venta.vendedor);
        $('#lista').text(venta_data.venta.lista);
        $('#prod_codigo').text(venta_data.venta.prod_codigo);
        $('#prod_nombre').text(venta_data.venta.prod_nombre);
        $('#uds').text(venta_data.venta.uds);
        $('#vu').text(venta_data.venta.vu);
        $('#subtotal').text(venta_data.venta.subtotal);
        $('#bonif').text(venta_data.venta.bonif);
        $('#modal_ventas').modal('show');
    };
</script>

Tarea Ajax

<script>
   $(function(){
        $('.show_tarea').on('click', function (e) {
            e.preventDefault();
            let tarea_id = $(this).attr('id');

            $.ajax({
                url:'/catalog/tareas-detail/',
                type:'POST',
                data: $('#form_tarea_'+tarea_id).serialize(),
                success:function(response){
                    console.log(response);
                    $('.show_tarea').trigger("reset");
                    openModal(response);
                },
                error:function(){
                    console.log('something went wrong here');
                },
            });
        });
    });

    function openModal(tarea_data){
        $('#creador').text(tarea_data.tarea.creador);
        $('#destinatario').text(tarea_data.tarea.destinatario);
        $('#titulo').text(tarea_data.tarea.titulo);
        $('#tarea').text(tarea_data.tarea.tarea);
        $('#resuelto').text(tarea_data.tarea.resuelto);
        $('#fecha_creacion').text(tarea_data.tarea.fecha_creacion);
        $('#fecha_limite').text(tarea_data.tarea.fecha_limite);
        $('#fecha_resuelto').text(tarea_data.tarea.fecha_resuelto);
        $('#empresa').text(tarea_data.tarea.empresa);
        $('#persona_empresa').text(tarea_data.tarea.persona_empresa);
        $('#modal_tareas').modal('show');
    };
</script>

Venta view

def VentaDetailView(request):
    ID = request.POST.get('id')
    ventas_todas = Ventas.objects.filter(pk=ID).get()

    venta = {
        "fecha": ventas_todas.fecha,
        "comprobante": ventas_todas.comprobante,
        "cliente": ventas_todas.cliente,
        "vendedor": ventas_todas.vendedor.nombre,
        "lista": ventas_todas.lista,
        "prod_codigo": ventas_todas.prod_codigo,
        "prod_nombre": ventas_todas.prod_nombre,
        "uds": ventas_todas.uds,
        "vu": ventas_todas.vu,
        "subtotal": ventas_todas.subtotal,
        "bonif": ventas_todas.bonif,
    }

    return JsonResponse({'venta': venta})

Tarea view

def TareaDetailView(request):
    ID = request.POST.get('id')

    tarea_select = Tareas.objects.filter(pk=ID).get()

    tarea = {
        "creador": tarea_select.creador.username,
        "destinatario": tarea_select.destinatario.username,
        "titulo": tarea_select.titulo,
        "tarea": tarea_select.tarea,
        "resuelto": tarea_select.resuelto,
        "fecha_creacion": tarea_select.fecha_creacion,
        "fecha_limite": tarea_select.fecha_limite,
        "fecha_resuelto": tarea_select.fecha_resuelto,
        "empresa": tarea_select.empresa.Nombre,
        "persona_empresa": tarea_select.persona_empresa.nombre,
    }

    return JsonResponse({'tarea': tarea})

Upvotes: 2

Views: 762

Answers (2)

Sigdev
Sigdev

Reputation: 392

You can add CSRF token to header like that too :

$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        xhr.setRequestHeader("X-CSRFToken",  getCookie('csrftoken'));
    }
});

Then you didn't need to manually add your CSRF token to all your ajax request.

Upvotes: 1

Mario Orlandi
Mario Orlandi

Reputation: 5849

No idea why the tareas part works ... but for sure I would add 'X-CSRFToken' header to both ajax calls:

$.ajax({
    url:'/catalog/ventas-detail/',
    type:'POST',
    data: $('#form_venta_'+venta_id).serialize(),
    headers: {'X-CSRFToken': getCookie('csrftoken')}
    ...
});

where:

function getCookie(name) {
    var value = '; ' + document.cookie,
        parts = value.split('; ' + name + '=');
    if (parts.length == 2) return parts.pop().split(';').shift();
}

Upvotes: 3

Related Questions