首页 > 解决方案 > 在 CBV 中使用复选框的 Django Ajax 发布请求

问题描述

我正在尝试通过仅使用复选框(而不是表单)向我的服务器发送 ajax 发布请求以添加或删除对象。这是我在视觉上得到的截图:

https://pasteboard.co/IMHHSa6.png

当我单击任何复选框时,我得到 http500(内部服务器错误)作为响应。在 cmd 我看到错误说没有匹配的查询:app1.models.Influencer.DoesNotExist:影响者匹配查询不存在。

问题是我很确定具有该 ID 的对象存在于数据库中。我花了很多时间检查 Django 的 CSRF 文档并观看有关 django-ajax 示例的 youtube 视频。这是我的代码:

视图.py

class InfluencerListView(LoginRequiredMixin, ListView):
    model = Influencer
    context_object_name = 'influencers' # not necessary, default is object_list

    def post(self, request, *args, **kwargs):
        inf_id = request.POST.get('inf.id')
        list_id = request.POST.get('list.id')
        i = Influencer.objects.get(id=inf_id)
        l = InfluencerList.objects.get(id=list_id)
        l.influencers.add(i)
        data = {
                'result' : 'some result'
        }
        return JsonResponse(data)     

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        logged_in_user = self.request.user
        context['myLists'] = logged_in_user.lists.annotate(influencers_count=Count('influencers'))
        return context

模型.py:

class Influencer(models.Model):
    # fields are not included for the sake of clarity

class InfluencerList(models.Model):
    name = models.CharField('Name:', max_length=20, blank=False)
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='lists')
    influencers = models.ManyToManyField('Influencer', related_name='lists') 

脚本.js

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = cookies[i].trim();
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

function myFunc(_self) {
    inf_id = _self.getAttribute('data-inf_id');
    list_id = _self.getAttribute('data-list_id');
    console.log(inf_id + " " + list_id); # I CAN SEE THOSE  IDS IN CONSOLE AND THEY EXIST IN DB
    var csrftoken = getCookie('csrftoken');
    if(_self.checked == true){
        console.log("checked!");

        $.ajaxSetup({
            beforeSend: function(xhr, settings) {
                if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", csrftoken);
                }
            }
        });

        $.ajax({
            method: 'POST',
            url: '/influencers',
            data: {
                'inf_id': inf_id,
                'list_id': list_id,
                'csrfmiddlewaretoken': csrftoken
            },
            dataType: 'json',
            success: function (data) {
                console.log("succes!");
            }
        });
    }
    else{
         console.log("unchecked!");       
    }
}

我还在我的视图文件中的某处添加了这一行(只要它在正文中就没有关系,因为我没有使用任何形式。如果我错了,请纠正我):

<input type='hidden' name='csrfmiddlewaretoken' value='{{ csrf_token }}' />        

标签: javascriptpythonjquerydjangoajax

解决方案


推荐阅读