Reputation: 1587
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.
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")
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)
<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(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.
[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
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