preetam
preetam

Reputation: 1587

Post returns 302 for ajax enabled class based view

I have been trying to do a basic implementation of login and logout forms through ajax in django. I am basically trying to eclose the standard auth login and logout into a ajax enabled class based view. The get is working but for somereason the post is returning a 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>

This is the url of the view:

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

you can ignore the redir_to and page_load attributes. The main thing is the 302 for post. It doesn't seem to enter the view at all.

Here is the console log of django webserver:

[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

Why am I getting a 302 only for the post ? How to solve this?

Upvotes: 0

Views: 667

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599630

Because you've decorated the post method with the user_passes_test decorator. That means you need to be logged in to post.

Upvotes: 1

Related Questions