DJANGO - 将 POST 数据转换为 JSON 并部分呈现 HTML

Posted

技术标签:

【中文标题】DJANGO - 将 POST 数据转换为 JSON 并部分呈现 HTML【英文标题】:DJANGO - convert POST data to JSON and render HTML partially 【发布时间】:2020-05-14 09:36:24 【问题描述】:

我一直在尝试将 AJAX 调用中的数据转换为 view.py 并转换回 html

JQuery/javascript

    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));
    

    $(document).ready(function() 

        var csrftoken = getCookie('csrftoken');

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

        // AJAX CALL TO VIEW
        $('a.play').click(function(e)
            e.preventDefault();
            var song_id = $(this).attr('id');
            alert(song_id);
            $.ajax(
                url: $(this).data('href'),
                type: 'POST',
                content: 'application/json; charset=utf-8',
                data: 
                    'song_id': song_id
                ,
                dataType: 'json',
                success: function(html) 
                    alert(html);
                    $('.player').replaceWith(html);
                ,
            );
        );
    );

views.py

    from django.shortcuts import render
    from django.http import Http404, JsonResponse
    from django.core import serializers
    from django.template.loader import render_to_string

    from .models import Song

    def change_song(request):
        if request.method == "POST":
            request.session['featured_song'] = request.POST.get('song_id', '')
            featured_song_id = request.session['featured_song']
            obj = Song.objects.get(pk=featured_song_id)
            song_list = Song.objects.all().order_by('-date') # list of objects
        context = 
            "featured_song": obj,
            "song_list": song_list,
        
        return render_to_string("music/player.html", context)

因此,在收到 AJAX 调用的 POST 后,我尝试将其返回以提醒其内容(调试)。第一个警报song_id 按原样返回 id,第二个警报甚至没有运行。当尝试调试时(我不记得确切的情况),当它运行时,第二个alert() 只返回整个 html 页面,而不仅仅是部分。

注意事项: 视图上的music/player.html 基本上是.player 容器。它没有包含或扩展或扩展其他模板的块。

【问题讨论】:

没有看到任何警报。 为什么不直接返回一个 JSON 对象并替换当前 HTML 中的数据呢?您可以使用 JSONResponse docs.djangoproject.com/en/3.0/ref/request-response/… 对不起。呼叫之前和成功之后的警报。忘记编辑了。 JSON 响应返回整个 HTML 页面,包括标题。 【参考方案1】:

所以,我最终解决了这个问题。一直都是模板/网址问题...

我试图访问子 APP url 路径 href="/change/" 并没有填写 APP href="/music/change/" 的完整 URL。我的想法是,由于模板在“音乐”APP的模板文件夹中,因此URL只需要URL的/change/部分。

话虽如此,我仍然会在此处发布代码以供将来参考,因为我还修复了一些 JSON 处理,以防有人需要使用类似的东西。

views.py

def change_song(request):
    featured_song_id = request.session['featured_song']
    song_list = Song.objects.all().order_by('-date') # list of objects
    if request.method == "POST":
        request.session['featured_song'] = request.POST['song_id']
        featured_song_id = request.session['featured_song']
    obj = Song.objects.get(pk=featured_song_id)
    serialized_obj = serializers.serialize('json', [obj])
    serialized_song_list = serializers.serialize('json', song_list)
    string_render = render_to_string('music/player.html')
    context = 
        'html': string_render,
        'obj': serialized_obj,
        'song_list': serialized_song_list,
    
    return JsonResponse(context, safe=False)

AJAX/jQuery/Javascript

    $('a.play').click(function(e)
        e.preventDefault();
        var song_id = $(this).attr('id');
        var this_url = $(this).attr('href');
        $.ajax(
            type: 'POST',
            url: this_url,
            data: 
                'song_id': song_id,
            ,
            dataType: 'json',
            success: function(data) 
                obj = JSON.parse(data.obj);
                title = obj[0]['fields']['title'];
                $('.replace').replaceWith(data.html);
                $('.player-title').html(title);
            
        );
    );

【讨论】:

【参考方案2】:

如果你想解析ajax调用json,在你的视图中执行以下操作:

        if request.method == "POST":
            content = request.body.decode('utf-8')
            data = json.loads(content)
            request.session['featured_song'] = data.get('song_id', '')
            featured_song_id = request.session['featured_song']

【讨论】:

在 /music/change 上仍然有相同的响应:整个 html 页面。意见'被定向到/音乐。会不会是个问题?

以上是关于DJANGO - 将 POST 数据转换为 JSON 并部分呈现 HTML的主要内容,如果未能解决你的问题,请参考以下文章

如何将列表转换为queryset django

如何将 django 表单输入转换为 python 数据?

如何防止“+”在 Django request.POST 方法中转换为空格?

如何将 django 变量正确转换为模板中的 json

django-rest-framework-从零开始-2-序列化类serializers.Serializer的使用

django:通用类视图 + POST = HTTP 405(不允许的方法)