如何在查询外部django视图时刷新DOM HTML的一部分

时间:2018-05-29 22:20:29

标签: javascript jquery ajax django django-views

Hello Awesome People!

关于 StackOverflow 的很多问题都是关于“如何通过jquery(from the same view/url)刷新dom”这不是我想要的。

有一个网站的大部分内容都是用ajax运行的,我想知道如何在查询外部django视图时刷新HTML DOM的一部分。

让我更清楚一些例子:

我有将all_users发送到模板

的视图
def usersList(request):
    all_users = User.objects.all()
    return render(request,'administration/users-list.html',{'all_users':all_users})

在模板中,我循环浏览all_users ...第二个<span>反映了用户的activation state

{% for u in all_users %}
    <span>{{forloop.counter}}.- {{u.name}} <span>
    <span id='user_{{u.id}}_state'>
        <button data-id='{{u.id}}' type='button' class='css-btn btn-circle'>
        {% if u.is_activate %} Active{% else %}Inactive{% endif %}
        </button>
    <span>
{% endfor %}

使用jquery,我向特定视图发送请求,该视图仅对activatedeactivate用户帐户负责。我们可以在网站的很多部分activate/deactivate用户,这就是我在不同视角中这样做的原因。

以下是观点:

def deactivateUser(request):
    user = request.user

    if user.has_perm('is_admin') and request.is_ajax() and request.method == 'POST':
        id_user = request.POST.get('id')
        targeted_user = get_object_or_deny(User,id=id_user)
        # get_object_or_deny is my own function
        it will get the object or raise PermissionDenied otherwise

        if targeted_user.is_activate:
            targeted_user.is_activate = False
            state = 'deactivated'
        else:
            targeted_user.is_activate = True
            state = 'activated'
        targeted_user.date_update_activation = NOW() # own function
        targeted_user.save()

        return JsonResponse({'done':True,'msg':'User successfully %s' %s state})
        # Here we return a JsonResponse
    raise PermissionDenied

现在,如何使用以下jquery内容刷新Dom以获取每个用户的当前状态

$(document).on('click','.btn-circle',function(){
    var id = $(this).data("id");
    $.ajax({
        url:'/u/de-activate/?ref={{ request.path }}',
        type:'post',
        data:{
            csrfmiddlewaretoken:"{{ csrf_token }}",
            id:id,
        },
        success:function(response){
            $("#user_"+id+"_state").replaceWith($("#user_"+id+"_state",response));
            if(response.created) alert(response.msg);
        },
        error:function(){
            alert("An error has occured, try again later");
        }
    });
});
  

请注意,all_users需要循环播放。 deactivateUser()返回一个Json响应,即使它没有返回它,也没关系。

1 个答案:

答案 0 :(得分:1)

您可以发送http响应,而不是json。

首先,只需移动要更改的html即可。在这种情况下,

    {% for u in all_users %}
    <div id="user-part">
        <span>{{forloop.counter}}.- {{u.name}} <span>
        <span id='user_{{u.id}}_state'>
            <button data-id='{{u.id}}' type='button' class='css-btn btn-circle'>
            {% if u.is_activate %} Active{% else %}Inactive{% endif %}
            </button>
        <span>
    </div>
    {% endfor %}

然后将其保存为user_part.html

其次,使用该html和上下文使您的视图返回HttpResponse。您可以使用HttpResponserender_to_response。我推荐render_to_response

context = {
    'all_users': all_users,
}
return render_to_response(
    'path_to/user_part.html',
    context=context,
)

第三,您只需更改脚本以替换您的html。

success: function(response){
    $('#user-part').html(response);
    prevent();
}