AJAX启用的类视图返回302

0 投票
1 回答
664 浏览
提问于 2025-04-18 02:28

我一直在尝试通过ajax在django中实现一个基本的登录和登出表单。我的目标是把标准的认证登录和登出功能放到一个支持ajax的类视图里。获取请求(get)是正常工作的,但不知道为什么,提交请求(post)却返回了302状态码。

views.py

class JsonAjaxView(View):
    template_name = None
    context = {}
    form = None
    context_object_name = 'context'
    #This tells whether yout need to
    #return back to same view after a post completion
    return_back = None  
    redir_to = None
    page_load = False
    @method_decorator(login_required)
    @method_decorator(user_passes_test(privilaged_user))
    @method_decorator(csrf_protect)
    def post(self, request):
        print("emp_users: Ajax Post")
        print("page_load = ", self.page_load)
        frm = self.form(request.POST)
        if frm.is_valid():
            frm.submit_action(request)
            if self.redir_to is not None:
                if self.page_load is True:
                    return HttpResponseRedirect(self.redir_to)
                else :
                    response_data = {}
                    response_data['redirect'] = self.redir_to
                    json_data = json.dumps(response_data)
                    return HttpResponse(json_data, content_type="application/json")
        print("emp_users post: Form invalid")
        get(request)
    def get(self, request):
        print("emp_users: Ajax get")
        #Look up the view block in the views and process it
        # then return the json
        if self.form is not None:
            print("emp ajax get: initializing form")
            frm = self.form()
            print("emp ajax get: Updating context")
            self.context.update(frm.get_context(request))
            self.context.update({'form':frm})
            self.context.update(csrf(request))
        if request.is_ajax():
            response_data  = {}
            page = render(request, self.template_name, self.context)
            print("emp ajax get: Page = ", page.content)
            response_data['page'] = page.content.decode("utf-8")
            print("emp ajax get: serializing")
            json_data = json.dumps(response_data)
            return HttpResponse(json_data, content_type="application/json")

forms.py

class login_form(AuthenticationForm):
    def get_context(self, request):
        request.session.set_test_cookie()
        current_site = get_current_site(request)
        redirect_field_name = request.get_host()
        ctxt = {}
        ctxt.update({
                'dummy' : 'dummy',
                'redirect_field_name' : redirect_field_name,
                })
        return ctxt

    def submit_action(self, *args):
        redirect_to = request.REQUEST.get(redirect_field_name, '')
        if not is_safe_url(url=redirect_to, host=request.get_host()):
            redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)

            # Okay, security check complete. Log the user in.
            auth_login(request, form.get_user())

            if request.session.test_cookie_worked():
                request.session.delete_test_cookie()

            return HttpResponseRedirect(redirect_to)

login.html

<script type="text/javascript" src="{{ STATIC_URL }}jquery/hr_base_nav_bar_main.js"></script>
{% if form.errors %}
<p>Your username and password didn't match. Please try again. </p>
{% endif %}

<form method="post" action="/emp_users/login">
{% csrf_token %}

<table>
<tr>
    <th>{{ form.username.label_tag }}</th>
    <td>{{ form.username }}</td>
</tr>
<tr>
    <th>{{ form.password.label_tag }}</th>
    <td>{{ form.password }}</td>
</tr>
</table>

<input type="submit" value="login" />
<input type="hidden" name="redirect_field_name" value="{{ redirect_field_name }}" />
</form>

这是视图的URL:

url(r'^logout/$', JsonAjaxView.as_view(template_name='emp_users/logout.html', form=logout_form, redir_to='index', page_load=True)),

你可以忽略redir_to和page_load这两个属性。主要的问题是post请求返回302状态码,似乎根本没有进入视图。

这是django web服务器的控制台日志:

[12/Apr/2014 16:13:10] "GET /emp_users/login HTTP/1.1" 200 754
[12/Apr/2014 16:13:10] "GET /static/jquery/hr_base_nav_bar_main.js?_=1397299121194 HTTP/1.1" 200 1541
[12/Apr/2014 16:13:10] "GET /static/jquery/hr_base_nav_bar_main.js?_=1397299121195 HTTP/1.1" 200 1541
[12/Apr/2014 16:13:10] "GET /static/jquery/hr_base_nav_bar_main.js?_=1397299121196 HTTP/1.1" 200 1541
[12/Apr/2014 16:13:10] "GET /static/jquery/hr_base_nav_bar_main.js?_=1397299121197 HTTP/1.1" 200 1541
[12/Apr/2014 16:13:55] "POST /emp_users/login HTTP/1.1" 302 0
emp_users: Ajax get
emp ajax get: initializing form
emp ajax get: Updating context
emp ajax get: Page =  b'<script type="text/javascript" src="http://127.0.0.1:8000/static/jquery/hr_base_nav_bar_main.js"
></script>\n\n\n<form method="post" action="/emp_users/login">\n<input type=\'hidden\' name=\'csrfmiddlewaretoken\' valu
e=\'LTxsYlAdmDtVwWwuO1ssG13reASB9itV\' />\n\n<table>\n<tr>\n\t<th><label for="id_username">Username</label></th>\n\t<td>
<input id="id_username" maxlength="254" name="username" type="text" /></td>\n</tr>\n<tr>\n\t<th><label for="id_password"
>Password</label></th>\n\t<td><input id="id_password" maxlength="4096" name="password" type="password" /></td>\n</tr>\n<
/table>\n\n<input type="submit" value="login" />\n<input type="hidden" name="redirect_field_name" value="127.0.0.1:8000"
 />\n</form>\n'
emp ajax get: serializing
[12/Apr/2014 16:13:55] "GET /emp_users/login?next=/emp_users/login HTTP/1.1" 200 754

为什么我只有在post请求时才会得到302状态码?该怎么解决这个问题呢?

1 个回答

1

因为你给这个发布方法加上了 user_passes_test 这个装饰器。这意味着你必须先登录才能发布内容。

撰写回答