【问题标题】:Use AJAX to update Django Model使用 AJAX 更新 Django 模型
【发布时间】:2021-03-03 10:10:30
【问题描述】:

我正在尝试了解如何在不加载新页面或明确让用户按下保存按钮的情况下使用 AJAX更新 Django 模型。我找到了很多关于使用 AJAX 从 Django 模型中获取结果的教程,但我还没有找到任何关于使用 AJAX 更新模型的教程。

这是我目前所拥有的

我有以下 Django 模型:

#models.py 

class Upload(models.Model):
    email = models.EmailField()
    title = models.CharField(max_length=100)
    language = models.ForeignKey('about.channel', on_delete=models.CASCADE, default='Other')
    date = models.DateField(auto_now_add=True)
    file = models.FileField()
    completed = models.BooleanField(default=False)

我正在通过表单接受这些上传,一切都很好。然后我通过以下视图在页面上显示它们:

#views.py

def submissions(request):
    context = {
        'uploads': Upload.objects.all().order_by('-completed', '-date')
    }

    return render(request, 'content/submissions.html', context)

此页面的模板:

#submissions.html

            <div class="row row-cols-1 row-cols-md-3">
                {% for upload in uploads %}
                <div class="col mb-4">
                    <div class="card">
                        <div class="card-body">
                            <h5 class="card-title"> {{ upload.title }} </h5>
                            <h6 class="card-subtitle"> {{upload.language}} </h6>
                            <a href="{{ upload.file.url }}" class="channel-link card-link" download> Download </a>
                            {% if upload.completed %}
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" value="" data-id="{{ upload.id }}" checked>
                                    <label class="form-check-label" for="{{ upload.id }}"> Completed </label>
                                </div>
                            {% else %}
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" value="" data-id="{{ upload.id }}">
                                    <label class="form-check-label" for="{{ upload.id }}"> Completed </label>
                                </div>
                            {% endif %}
                        </div>
                    </div>
                </div>
            {% endfor %}
            </div>

这是页面的一部分:

复选框起作用,并在 completed 模型字段上返回适当的选中与未选中。

我正在尝试了解如何将其连接到 AJAX,以便能够通过单击页面上每张卡上的复选框来更新 completed 模型字段,而无需加载新页面/模型或按一个保存按钮。我尝试了以下视图来更新模型,但没有运气:

#views.py

def completed(request, *args, **kwargs):
    upload = Upload.objects.get(id=id)
    upload.completed = not upload.complete
    upload.save()

    return JsonResponse({'status': 200})

还有 jQuery/AJAX:

$('.form-check').on('click', '.form-check-input', function() {
    var dataID = $(this).data('id');
    $.ajax({
        type: 'POST',
        url: 'content/completed/',
        data: {
            id: dataID
        },
        success: function () {
            console.log('Success')
        }
    })
});

唉,我什么也得不到。我确定我用于更新的视图和 AJAX 调用都有问题,但我不知道下一步该做什么。

【问题讨论】:

    标签: javascript jquery django ajax django-models


    【解决方案1】:

    我假设您的表单使用正确的数据成功触发了您的 AJAX 调用。也许您没有正确访问您的 AJAX 发布参数

    你的 API:

    def completed(request)
        id = request.POST.get('id')   # Add this line
    
        upload = Upload.objects.get(id=id)
        upload.completed = not upload.complete
        upload.save()
        
        return JsonResponse({'status': 200})
    

    如果这不能解决问题,请告诉我您从后端收到了哪些消息,以及您在 Ajax 调用中发送了哪些类型的数据。如果您使用 FireFox,请按 ctrl+shift+I 并单击 Network 选项卡以查看您从 Ajax 调用发送的数据。

    关于您对 CSRF 的评论,请在调用 $.ajax() 之前尝试将此代码(csrfSafeMethod() 和 $.ajaxSetup())

    function csrfSafeMethod(method) {
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    };
    
    ...
    
    $('.form-check').on('click', '.form-check-input', function() {
        var dataID = $(this).data('id');
        
        $.ajaxSetup({
            beforeSend: function (xhr, settings) {
                if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                    // Only send the token to relative URLs i.e. locally.
                    xhr.setRequestHeader("X-CSRFToken", Cookies.get('csrftoken'));
                }
            }
        });
    
        $.ajax({
            url: "content/completed/",
            type: "POST",
            data: {
                id: dataID
            },
            success: function () {
                console.log('Success')
            }
        })
    });
    

    这就是我为我的 API 处理 CSRF 而不将它们放入 @csrf_exempt 的方式,也许它也对你有用

    【讨论】:

    • 就是这样!现在另一个问题。我只是将视图移至@csrf_exempt,但我宁愿使用 CSRF 进行保护。当页面上没有表单时,最好的处理方法是什么?
    • 我对您的评论的答案进行了更新,答案太长,无法放入 cmets :)
    猜你喜欢
    • 2017-04-18
    • 1970-01-01
    • 2020-08-05
    • 2017-08-14
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    相关资源
    最近更新 更多