Django-AttributeError 'User' object has no attribute 'backend' (But....it does?)

DjangoAuthenticationDjango ModelsDjango Authentication

Django Problem Overview


In order to sign users in after registering them, I manually set the user.backend property. It normally works in my views. In this instance, I'm trying to register the user via AJAX. It is raising an AttributeError.

Here is my code:

 def register_async(request):
    if request.method=='POST':
		
	userform=MyUserCreationForm(request.POST)
	if userform.is_valid():
		#username of <30 char is required by Django User model.  I'm storing username as a hash of user email 
				
		user=userform.save(commit=False)
		user.username=hash(user.email)
		user.backend='django.contrib.auth.backends.ModelBackend'
		user.save()
		
		
		auth.login(request,user)
		user_status=1
		user_fname=user.first_name
		user_data=[{'user_status':user_status, 'user_fname':user_fname}]
		json_data=json.dumps(user_data)
		response=HttpResponse()
		response['Content-Type']="text/javascript"
		response.write(json_data)
		return response	

	else:
		user_data=[{'user_status':"0"}]
		json_data=json.dumps(user_data)
		response=HttpResponse()
		response['Content-Type']="text/javascript"
		response.write(json_data)
		return response	
else:
	return HttpResponse()

EDIT-- HERE'S THE AJAX. IT SEEMS PRETTY STANDARD

     //ajax registration.  
$('input#register_submit').click(function(event){
	$(this).attr('disabled','disabled');
	$('<div class="register-animation"><img src="{{site}}media/ajax-loader3.gif"/></div>').appendTo('#register_modal_btn');
	
	$.post("/register/", $('div#register_side form').serialize(), 
		function(data){
			$.each(data,function(){
			if(this.user_status==1){
				$('.register-animation').remove();
				$('.right_section .top').html('<ul><li class="sep_nav">Hi, '+ this.user_fname + '</li><li class="sep+nav"><a href="http://nabshack.com/logout/">Log Out</a></li><li class="refar_friend"><a href="http://nabshack.com/referral/">Refer a friend and get $50</a></li></ul>');
				$('#post_login_modal').dialog("close");
	
				$('a.login').unbind('click');
				$('li a.account').unbind('click');
	
			}		
			else{
			$('input#register_submit').removeAttr('disabled');
			$('.register-animation').remove();
			window.location='{{site}}register';
			}
			
		});
	},'json');
	return false;
	event.stopPropagation();
});

Pretty much this exact code works in non-ajax views for me. What gives?

Thanks

Django Solutions


Solution 1 - Django

You must call authenticate before you can call login. authenticate sets an attribute on the object noting which backend has successfully validated it and clearing it for login, which isn't happening in your code (and that's the attribute that is missing).

Documentation: https://docs.djangoproject.com/en/1.8/topics/auth/default/#how-to-log-a-user-in -- check out the little callout that says "calling authenticate() first".

Solution 2 - Django

I'll post this as an answer, But I owe it to https://stackoverflow.com/users/558699/ben in the comments above, and https://stackoverflow.com/a/5837046/1467342. I was scanning this question and missed that what I was looking for was in the comments. Adding a backend manually has been a (hacky) fix for me twice so far:

user.backend = 'django.contrib.auth.backends.ModelBackend'
login(request, user)

In both cases, I'm relying on other authentication methods (email confirmation and admin authenticated session) for verifying permission to log in as this user.

Solution 3 - Django

in Django 1.10, django.contrib.auth.login now takes a backend= keyword argument!

https://code.djangoproject.com/ticket/24855

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBenView Question on Stackoverflow
Solution 1 - DjangoLuke SneeringerView Answer on Stackoverflow
Solution 2 - DjangojstaabView Answer on Stackoverflow
Solution 3 - DjangoDavid LamView Answer on Stackoverflow