I'm trying to create a simple user registration in Django and I get this error. I've looked it up here on stackoverflow: 'AnonymousUser' object has no attribute 'backend', Django Register Form 'AnonymousUser' object has no attribute 'backend' and tried calling authentication before login. But I keep getting this error.
Can anyone please help me with this?
Here is the traceback
Traceback:
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py" in get_response
114. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Library/Python/2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
57. return view_func(*args, **kwargs)
File "/Users/harisaghadi/Dropbox/Senior Project/Django Tutorials/mysite/meddy1/views.py" in signup_user
51. login(request, new_user)
File "/Library/Python/2.7/site-packages/django/contrib/auth/__init__.py" in login
85. request.session[BACKEND_SESSION_KEY] = user.backend
File "/Library/Python/2.7/site-packages/django/utils/functional.py" in inner
214. return func(self._wrapped, *args)
Exception Type: AttributeError at /meddy1/signup/
Exception Value: 'AnonymousUser' object has no attribute 'backend'
Here is my forms.py
class UserCreationForm(forms.ModelForm):
"""
A form that creates a user, with no privileges, from the given username and
password.
"""
error_messages = {
'duplicate_username': _("A user with that username already exists."),
'password_mismatch': _("The two password fields didn't match."),
}
email = forms.EmailField(required=True, widget=forms.TextInput(attrs={'class': 'form-control','placeholder':'Please enter a valid email address so we can reach you.'}))
username = forms.RegexField(label=_("Username"), max_length=30,
regex=r'^[\w.#+-]+$',
help_text=_("Required. 30 characters or fewer. Letters, digits and "
"#/./+/-/_ only."),
error_messages={
'invalid': _("This value may contain only letters, numbers and "
"#/./+/-/_ characters.")})
password1 = forms.CharField(label=_("Password"),
widget=forms.PasswordInput)
password2 = forms.CharField(label=_("Password confirmation"),
widget=forms.PasswordInput,
help_text=_("Enter the same password as above, for verification."))
class Meta:
model = User
fields = ("username",)
def clean_username(self):
# Since User.username is unique, this check is redundant,
# but it sets a nicer error message than the ORM. See #13147.
username = self.cleaned_data["username"]
try:
User._default_manager.get(username=username)
except User.DoesNotExist:
return username
raise forms.ValidationError(
self.error_messages['duplicate_username'],
code='duplicate_username',
)
def clean_password2(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError(
self.error_messages['password_mismatch'],
code='password_mismatch',
)
return password2
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
userProfile = DoctorSeeker(user=user, name=name, email=email)
userProfile.save()
return user
views.py
def index(request):
return HttpResponse("Welcome to Meddy")
# -------------------- Authentication ----------------------
def signup(request):
return render(request, 'meddy1/signup.html', {})
#csrf_exempt
def signup_user(request):
if request.method == 'POST':
form = UserCreationForm(request.POST,request.FILES)
if form.is_valid():
new_user = authenticate(username=request.POST['username'],password=request.POST['password1'])
login(request, new_user)
return HttpResponseRedirect(reverse('index'))
else:
form = UserCreationForm()
return render(request, "meddy1/signup.html", {'form': form,'usersignup':True})
def login_user(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username,password=password)
if user:
return render(request, 'meddy1/index.html')
else:
return HttpResponseRedirect('/')
def logout_user(request):
logout(request)
return HttpResponseRedirect('/')
models.py
class DoctorSeeker(models.Model):
name = models.CharField(max_length=30)
email = models.EmailField()
user = models.ForeignKey(User, unique=True)
def __unicode__(self):
return u"%s %s" % (self.name, self.email)
Since you found the similar posts, i take it, you understand, that your authenticate does not really authenticate anything. It fails for some reason.
I understand that the view you are showing us is trying to accomplish 2 things- create user and log him in? Right? Since its name is signup_user.
Well. You have UserCreationForm, but you do not save it. So you cant really authenticate an user, that does not yet exist in the system. Save your form first, then call authenticate.
Related
I've searched everywhere for a solution to this problem. Yet, no resolution as of yet.
The problem
After successfully creating a user via a front-end registration form, upon logging in using a front-end login form, the "Authenticate" function returns "None".
The interesting part, if I am to create a new user via the admin panel (using similar code), I am then able to login via the front-end login form.
The custom user model I've created does use an email address as the Username. If a user registers using the front-end register form, the user details are saved to the database, where the password is properly hashed.
Here is the code:
From Forms.py
from django import forms
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from .models import User as CustomUser
from django.conf import settings
class RegisterForm(forms.ModelForm):
password1 = forms.CharField(label='', widget=forms.PasswordInput)
password2 = forms.CharField(label='', widget=forms.PasswordInput)
class Meta:
model = CustomUser
fields = ('email', 'full_name')
def __init__(self, *args, **kwargs):
super(RegisterForm, self).__init__(*args, **kwargs)
self.fields['email'].widget.attrs.update(
{'class': 'form-control loginInput', 'placeholder': 'Your Email (you#company.com)'})
self.fields['full_name'].widget.attrs.update(
{'class': 'form-control loginInput', 'placeholder': 'Your Full Name'})
self.fields['email'].label = ''
self.fields['full_name'].label = ''
self.fields['password1'].widget.attrs.update(
{'class': 'form-control loginInput', 'placeholder': 'Your Password'})
self.fields['password2'].widget.attrs.update(
{'class': 'form-control loginInput', 'placeholder': 'Confirm Password'})
def clean_email(self):
email = self.cleaned_data.get('email')
qs = CustomUser.objects.filter(email=email)
if qs.exists():
raise forms.ValidationError("email is taken")
return email
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
# Saving the provided password in hashed format
user = super(RegisterForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class UserAdminCreationForm(forms.ModelForm):
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta:
model = CustomUser
fields = ('email',)
def clean_password2(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
user = super(UserAdminCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
From Views.py
def register(request):
registered = False
if request.method == 'POST':
registration = forms.RegisterForm(data=request.POST)
if registration.is_valid():
member = registration.save()
member.set_password(member.password)
member.save()
registered = True
else:
print(registration.errors)
else:
registration = forms.RegisterForm()
print("Registered: " + str(registered))
return render(request, 'accounts/registration.html',
{'registration_form': registration,
'registered': registered,
})
def user_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user not None:
if user.is_active:
login(request, user)
return HttpResponseRedirect(reverse('account_index'))
else:
HttpResponse("ACCOUNT NOT ACTIVE")
else:
print("Someone tried to login and failed!")
print("Email: {} and password {}".format(username, password))
return HttpResponse("invalid login details supplied!")
else:
return render(request, 'accounts/user_login.html', {})
I'm at a loss at the present time. Could use some direction or advice.
Ok, I've resolved this issue. It seems as though I just needed to sleep on it.
Here is the code that was causing the issue:
In Views.py
member.set_password(member.password)
It seems as if though it was setting a hashed version of the password. But "set_password" must be the raw version of the password.
To fix this I changed it to:
member.set_password(request.POST.get('password1'))
Behold, it works!
I'm using a view to create new users in Django. And then I have another view to log them in.
But when I create a user, and I try to log in with authenticate(username=username_post, password=password_post), I get None, so it displays in the template 'Wrong username or password.'.
In my database, I see new registers every time I create a new user. However, as the password is encrypted, I can't say if the problem is the login view, or the register view.
However, the super user that I created through the command line after I first installed django, is able to login with no problem, so that makes me thing that the problem is when I create the user.
These are my Login and Register views:
class Login(View):
form = LoginForm()
message = None
template = 'settings/blog_login.html'
def get(self, request, *args, **kwargs):
if request.user.is_authenticated():
return redirect('settings:index')
return render(request, self.template, self.get_context())
def post(self, request, *args, **kwargs):
username_post = request.POST['username']
password_post = request.POST['password']
user = authenticate(username=username_post, password=password_post)
if user is not None:
login(request, user)
return redirect('settings:index')
else:
self.message = 'Wrong username or password.'
return render(request, self.template, self.get_context())
def get_context(self):
return {'form': self.form, 'message': self.message}
class Register(CreateView):
success_url = reverse_lazy('settings:login')
model = User
template_name = 'settings/blog_register.html'
form_class = RegisterForm
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.set_password(self.object.password)
self.object.save()
return HttpResponseRedirect(self.get_success_url())
And these are my forms:
class LoginForm(forms.Form):
username = forms.CharField(max_length=20, label='Username')
password = forms.CharField(label='Password', widget=forms.PasswordInput())
class RegisterForm(forms.ModelForm):
username = forms.CharField(max_length=20, label='Username')
password1 = forms.CharField(label='Password', widget=forms.PasswordInput(),
error_messages={'required': 'Required field.',
'unique': 'Username already used.',
'invalid': 'Not valid username.'})
password2 = forms.CharField(label='Retype password', widget=forms.PasswordInput(),
error_messages={'required': 'Required field.'})
email = forms.EmailField(error_messages={'required': 'Required field.',
'invalid': 'Invalid email.'})
def clean(self):
clean_data = super(RegisterForm, self).clean()
password1 = clean_data.get('password1')
password2 = clean_data.get('password2')
if password1 != password2:
raise forms.ValidationError('Passwords are different.')
return self.cleaned_data
def clean_email(self):
email = self.cleaned_data.get('email')
username = self.cleaned_data.get('username')
if email and User.objects.filter(email=email).exclude(
username=username).exists():
raise forms.ValidationError('Email already used.')
return email
class Meta:
model = User
fields = ('username', 'password1', 'password2', 'email')
Please, let me know if you need more info.
You don't have a field called 'password' in your form - you just have 'password1' and 'password2' - so nothing is saved to the model object's actual password field. So, when you do self.object.set_password(self.object.password), you're actually setting a blank password.
Instead, you should get the value from your form's password1 field:
self.object.set_password(self.form.cleaned_data['password1'])
I have looked at a lot of posts that had similar issues and the answers did nothing for my code.
I am using a custom registration form for a site I'm working on that makes email required. most of the code in it is based off of the one built in to django. I have tried to create a new form class based on django.contrib.auth.forms.UserCreationForm and still get the same error.
The form based on the one in django
class UserCreateFrom(UserCreationForm):
"""
A form that creates a user, with no privileges, from the given username and
password.
"""
error_messages = {
'duplicate_username': _("A user with that username already exists."),
'duplicate_email': _("That email is already in use"),
'password_mismatch': _("The two password fields didn't match."),
}
email = forms.EmailField(label=_("Email Address"),
required=True,
help_text="Required. Your Email Address for password resets, and other emails from us")
def clean_email(self):
email = self.cleaned_data["email"]
try:
User._default_manager.get(email=email)
except User.DoesNotExist:
return email
raise forms.ValidationError(
self.error_messages['duplicate_email'],
code='duplicate_email',
)
the form currently in use
class UserCreateFrom(forms.ModelForm):
"""
A form that creates a user, with no privileges, from the given username and
password.
"""
error_messages = {
'duplicate_username': _("A user with that username already exists."),
'duplicate_email': _("That email is already in use"),
'password_mismatch': _("The two password fields didn't match."),
}
username = forms.RegexField(label=_("Username"), max_length=30,
regex=r'^[\w.#+-]+$',
help_text=_("Required. 30 characters or fewer. Letters, digits and "
"#/./+/-/_ only."),
error_messages={
'invalid': _("This value may contain only letters, numbers and "
"#/./+/-/_ characters.")
}
)
email = forms.EmailField(label=_("Email Address"),
required=True,
help_text="Required. Your Email Address for password resets, and other emails from us")
password1 = forms.CharField(label=_("Password"),
widget=forms.PasswordInput)
password2 = forms.CharField(label=_("Password confirmation"),
widget=forms.PasswordInput,
help_text=_("Enter the same password as above, for verification."))
class Meta:
model = User
fields = ("username",)
def clean_username(self):
# Since User.username is unique, this check is redundant,
# but it sets a nicer error message than the ORM. See #13147.
username = self.cleaned_data["username"]
try:
User._default_manager.get(username=username)
except User.DoesNotExist:
return username
raise forms.ValidationError(
self.error_messages['duplicate_username'],
code='duplicate_username',
)
def clean_email(self):
email = self.cleaned_data["email"]
try:
User._default_manager.get(email=email)
except User.DoesNotExist:
return email
raise forms.ValidationError(
self.error_messages['duplicate_email'],
code='duplicate_email',
)
def clean_password2(self):
password1 = self.cleaned_data["password1"]
password2 = self.cleaned_data["password2"]
if password1 and password2 and password1 != password2:
raise forms.ValidationError(
self.error_messages['password_mismatch'],
code='password_mismatch',
)
return password2
def save(self, commit=True):
user = super(UserCreateFrom, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
the view, I have not been able to work on if the form is valid since I cant get it to work with no data UserCreateFrom is my custom registration form imported from froms.py in the same app.
#sensitive_post_parameters()
#csrf_protect
#never_cache
def register(request):
"""
Allow registration of new users
:param request:
:return:
"""
context = {}
form = UserCreateFrom(data=request.post)
context.update({'form': form})
if request.method == 'POST' and form.is_valid():
return render(request, 'test.html', context)
else:
return render(request, 'register.html', context)
if I switch form = UserCreateFrom(data=request.post) to form = UserCreateFrom(request) I get 'WSGIRequest' object has no attribute 'get' error, but this way at least errors in the template right where the form is called via `{{ form }}, and not the view.
The data attribute is called request.POST.
But you should move that into the block that checks the method.
I'm trying to create edit user profile functionality. But I get the following error
Traceback:
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py" in get_response
114. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/views.py" in update_profile
60. form.save()
File "/forms.py" in save
108. user = super(UserUpdateForm, self).save(commit=False)
Exception Type: AttributeError at /editseekerprofile/
Exception Value: 'super' object has no attribute 'save'
Here is my views.py
def update_profile(request):
args = {}
if request.method == 'POST':
form = UserUpdateForm(request.POST)
if form.is_valid():
form.save()
return render(request,'meddy1/seekerprofile.html',{'doctorSeeker': profile})
else:
form = UserUpdateForm()
args['form'] = form
return render(request, 'meddy1/editseekerprofile.html', args)
Here is my forms.py
class UserUpdateForm(forms.Form):
name = forms.CharField(max_length=200, widget=forms.TextInput(attrs={'class': 'form-control','placeholder':'FirstName LastName'}))
email = forms.EmailField(required=True, widget=forms.TextInput(attrs={'class': 'form-control','placeholder':'Please enter a valid email address so we can reach you. No spam. Ever.'}))
password1 = forms.CharField(label="Old Password",widget=forms.PasswordInput(attrs={'class': 'form-control','placeholder':'Enter your password to save the changes.'}),required=False)
password2 = forms.CharField(label="New Password?",widget=forms.PasswordInput(attrs={'class': 'form-control','placeholder':'Only enter new password if you want to change it.'}),required=False)
password3 = forms.CharField(label="Confirm New Password",widget=forms.PasswordInput(attrs={'class': 'form-control','placeholder':'Confirm New Password'}),required=False)
class Meta:
model = DoctorSeeker
fields = ("name","email")
class Meta:
model = User
fields = ("password2", "password3")
def clean_password2(self):
password2 = self.cleaned_data.get("password2")
password3 = self.cleaned_data.get("password3")
if password2 and password3 and password2 != password3:
raise forms.ValidationError(
self.error_messages['password_mismatch'],
code='password_mismatch',
)
return password2
def save(self, commit=True):
user = super(UserUpdateForm, self).save(commit=False)
user.set_password(self.cleaned_data["password2"])
fullName = self.cleaned_data["name"]
Email = self.cleaned_data["email"]
if commit:
user.save()
userProfile = DoctorSeeker(user=user, name=fullName, email=Email)
userProfile.save()
return user
Just to clarify, I'm saving user information in two different models, one is the default user model and the other one is DoctorSeeker.
forms.Form has no method called save, thats why you can't override it. forms.ModelForm has the save method which you can override.
I am creating user authentication form, on entering data and submitting, I get this error:
AttributeError at /register/
'RegistrationForm' object has no attribute 'username'
at ` username=form.username,
I have checked all the solutions with the same problem and applied them but no one is solving it(like that is_valid()). how do I get it right? here is the code:
from django.http import HttpResponse
def register_page(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
user = User.objects.create_user(
username=form.clean_data['username'],
password=form.clean_data['password1'],
email=form.clean_data['email'])
return HttpResponseRedirect('/register/success/')
else:
form = RegistrationForm()
variables = RequestContext(request, {
'form': form})
return render_to_response(
'registration/register.html',
variables)
def logout_page(request):
logout(request)
return HttpResponseRedirect('/')
def main_page(request):
return render_to_response(
'main_page.html', RequestContext(request))
def user_page(request, username):
try:
user = User.objects.get(username=username)
except:
raise Http404('Requested user not found.')
bookmarks = user.bookmark_set.all()
template = get_template('user_page.html')
variables = RequestContext(request, {
'username': username,
'bookmarks': bookmarks
})
output = template.render(variables)
return HttpResponse(output)
forms.py
import re
class RegistrationForm(forms.Form):
username = forms.CharField(label='Username', max_length=30)
email = forms.EmailField(label='Email')
password1 = forms.CharField(
label='Password',
widget=forms.PasswordInput()
)
password2 = forms.CharField(
label='Password (Again)',
widget=forms.PasswordInput())
def clean_password2(self):
if 'password1' in self.clean_data:
password1 = self.clean_data['password1']
password2 = self.clean_data['password2']
if password1 == password2:
return password2
raise forms.ValidationError('Passwords do not match.')
def clean_username(self):
username = self.clean_data['username']
if not re.search(r'^\w+$', username):
raise forms.ValidationError('Username .')
try:
User.objects.get(username=username)
except ObjectDoesNotExist:
return username
raise forms.ValidationError('Username is already taken.')
Its cleaned_data, not clean_data:
username = form.cleaned_data['username']
Do this for other form data as well, like password1 and email.
Some background in the reason for this can be found in Django documentation. Basically, the methods are called clean_fieldname but after cleaning the data is in cleaned_fieldname. Note the distinction.