I'm trying to create a superuser but it's giving the above error.
And I can't exactly find at which line I'm getting the error.
views.py
from django.shortcuts import render
from django.contrib.auth import authenticate,login,logout
from .models import *
from django.http import HttpResponseRedirect
from django.urls import reverse
from .form import *
from django.db import IntegrityError
# Create your views here.
def index(request):
if not myUser.is_authenticated:
message = "signed in as {Customer.first_name}"
else :
message = "please sign in"
return render(request, "auctions/index.html",{
"listings": Listings.objects.all(),
"message":message
})
def login_view(request):
if request.method == "POST":
form = loginForm()
email = request.POST["email"]
password = request.POST["password"]
user = authenticate(request,username=email,password=password)
if user is not None:
login(request,email,password)
return HttpResponseRedirect(reverse('index'))
else:
return render(request, "auctions/login.html",{
"form": form ,
"message": "username/password not valid"
})
return render(request, "auctions/login.html",{
"form": loginForm()
})
def logout_view(request):
logout(request)
return render(request, "auctions/login.html")
def register(request):
if request.POST == "POST":
form = registerForm()
email = request.POST["email"]
# check passwords are same
password = request.POST["password"]
confirmation = request.POST["confirmation"]
if password != confirmation:
return render (request, "auctions/register.html",{
"form": form,
"message": "Passwords does not match"
})
# Attempt to create new user
try:
user = myUser.objects.create_user(email,password)
user.save()
except IntegrityError:
return render(request, "auctions/register.html", {
"form":form,
"message": "Username is already taken"
})
login(request,user)
return HttpResponseRedirect(reverse('index'))
return render(request, "auctions/register.html", {
"form": registerForm()
})
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser,BaseUserManager
from django.utils.translation import ugettext_lazy as _
# Create your models here.
class myUserManager(BaseUserManager):
"""
custom user model manager where email is unique indentifiers for authenticaton
instead of usernames.
"""
def create_user(self, email, password, **extra_fields):
"""
Create and save a User with the given email and password.
"""
if not email:
raise ValueError(_('The Email must be set'))
email = self.normalize_email(email)
user = self.model(email, **extra_fields)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **extra_fields):
"""
Create and save a SuperUser with the given email and password.
"""
extra_fields.setdefault('is_staff',True)
extra_fields.setdefault('is_superuser',True)
extra_fields.setdefault('is_active',True)
if extra_fields.get('is_staff') is not True:
raise ValueError(_('Superuser must have is_staff= True'))
if extra_fields.get('is_superuser') is not True:
raise ValueError(_('Superuser must have is_superuser=True.'))
return self.create_user(email,password, **extra_fields)
class myUser(AbstractUser):
username = None
email = models.EmailField(_('email address'), unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = myUserManager()
def __str__(self):
return f'{self.email}'
class Listings(models.Model):
listing_name = models.CharField(max_length=50)
price = models.IntegerField()
date_listed = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
item_image = models.ImageField()
description = models.TextField(max_length=200, default="Description Not Available")
def __str__(self):
return f'{self.listing_name}'
I even tried deleting files inside migrations and remigrating them but it still shows the same error.
Thanks and I really appreciate your efforts in helping me
The function django.contrib.auth.login is defined as def login(request, user, backend=None). You pass it the wrong arguments (login(request,email,password)).
Your view should be:
def login_view(request):
if request.method == "POST":
form = loginForm()
email = request.POST["email"]
password = request.POST["password"]
user = authenticate(request,username=email,password=password)
if user is not None:
login(request, user) # ← here
return HttpResponseRedirect(reverse('index'))
else:
return render(request, "auctions/login.html",{
"form": form ,
"message": "username/password not valid"
})
return render(request, "auctions/login.html",{
"form": loginForm()
})
Also in your create_user method you write self.model(email, **extra_fields) but that's incorrect. Your method should be:
def create_user(self, email, password, **extra_fields):
"""
Create and save a User with the given email and password.
"""
if not email:
raise ValueError(_('The Email must be set'))
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save()
return user
Related
I want a signup page with 3 fields (email, password and repeat password). My goal is that when the user enters the email address, it is also saved in the database as a username. I would be super happy if someone could help me, I've been sitting for x hours trying to solve this problem. Thanks very much!
model.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
email_confirmed = models.BooleanField(default=False)
#receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()
forms.py
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
# Sign Up Form
class SignUpForm(UserCreationForm):
# first_name = forms.CharField(max_length=30, required=False, help_text='Optional')
# last_name = forms.CharField(max_length=30, required=False, help_text='Optional')
email = forms.EmailField(max_length=254, help_text='Enter a valid email address')
class Meta:
model = User
fields = [
'username',
'password1',
'password2',
]
views.py
from django.contrib import messages
from django.contrib.auth.models import Group
from django.contrib.sites.shortcuts import get_current_site
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from django.template.loader import render_to_string
from .token import AccountActivationTokenGenerator, account_activation_token
from django.shortcuts import render, redirect
from .forms import *
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth import get_user_model, login
from django.utils.http import urlsafe_base64_decode
from django.views.generic import View, UpdateView
from django.contrib.auth.decorators import login_required
from .decorators import *
from django.urls import reverse_lazy
from django.utils.encoding import force_str
#unauthenticatedUser
def Example_login(request):
if request.method == 'POST':
email = request.POST.get('email')
password = request.POST.get('password')
user = authenticate(request, username=email, password=password)
if user is not None:
login(request, user)
return redirect('Example_dashboard')
else:
messages.info(request, 'Username OR password is incorrecct')
context = {}
return render(request, 'accounds/templates/Example_login.html', context)
def reset_passwrd(request):
return render(request, "reset_password.html")
#login_required(login_url='login')
def Example_dashboard(request):
form = MembersForm()
current_user = request.user
name = current_user.username.split(".")[0]
context = {'form': form, "cunrrent_user": name}
return render(request, 'example_dashboard.html', context)
def Login(request):
if request.method == 'POST':
email = request.POST.get('Benutzername')
password = request.POST.get('Passwort')
user = authenticate(request, username=email, password=password)
if user is not None:
login(request, user)
return redirect('Example_dashboard')
else:
messages.info(request, 'Username OR password is incorrecct')
return render(request, "login.html")
def logoutUser(request):
logout(request)
return redirect('login')
def registrierung(request):
return render(request, "registrierung.html")
#unauthenticatedUser
def Example_register(request):
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
user = form.save()
#username = form.cleaned_data.get('usernname')
group = Group.objects.get(name='studends')
user.groups.add(group)
messages.success(request, 'Account was created' )
return redirect('login')
contex = {'form' : form}
return render(request, 'exampl_register.html',contex)
# Sign Up View
class SignUpView(View):
form_class = SignUpForm
template_name = 'signup.html'
def get(self, request, *args, **kwargs):
form = self.form_class()
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False # Deactivate account till it is confirmed
user.save()
current_site = get_current_site(request)
subject = 'Activate Your MySite Account'
message = render_to_string('account_activation_email.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': account_activation_token.make_token(user),
})
user.email_user(subject, message)
messages.success(request, ('Please Confirm your email to complete registration.'))
return redirect('login')
return render(request, self.template_name, {'form': form})
class ActivateAccount(View):
def get(self, request, uidb64, token, *args, **kwargs):
try:
uid = force_str(urlsafe_base64_decode(uidb64))
user = User.objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
if user is not None and account_activation_token.check_token(user, token):
user.is_active = True
user.profile.email_confirmed = True
user.save()
login(request, user)
messages.success(request, ('Your account have been confirmed.'))
return redirect('login')
else:
messages.warning(request, ('The confirmation link was invalid, possibly because it has already been used.'))
return redirect('login')
I Need your help
If you want to use email instead of the default username, you have to overwrite the default User model with the custom one
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
class User(AbstractBaseUser, PermissionsMixin):
# Use the email for logging in
email = models.EmailField(max_length=254, unique=True)
USERNAME_FIELD = 'email'
I'm currently learning django. Here is my problem: user created using terminal with createsuperuser can log in to the website, but users created with my register page are not. Users created using my registration appear in the admin panel and all fields match the entered data. I guess the problem is somewhere in CustomUserManager(before creating it login worked properly)
models.py
class CustomUserManager(BaseUserManager):
def create_superuser(self, email, username, first_name, bio, password, **other_fields):
other_fields.setdefault('is_staff', True)
other_fields.setdefault('is_superuser', True)
other_fields.setdefault('is_active', True)
if other_fields.get('is_staff') is not True:
raise ValueError("Superuser must be assigned staff to True")
if other_fields.get('is_superuser') is not True:
raise ValueError("Superuser must be assigned superuser to True")
return self.create_user(email, username, first_name, bio, password, **other_fields)
def create_user(self, email, username, first_name, bio, password, **other_fields):
if not email:
raise ValueError("You must provide an email.")
email = self.normalize_email(email)
user = self.model(email=email, username=username, first_name=first_name, bio=bio,
**other_fields)
user.set_password(password)
user.save()
return user
class User(AbstractBaseUser, PermissionsMixin):
first_name = models.CharField(max_length=200, null=True, verbose_name="Имя")
username = models.CharField(
max_length=50, null=True, verbose_name="Никнейм", unique=True)
email = models.EmailField(null=True, unique=True)
bio = models.TextField(null=True, blank=True)
avatar = models.ImageField(null=True, default="avatar.svg", blank=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
objects = CustomUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name','username','bio']
def __str__(self):
return self.username
views.py
def loginPage(request):
page = 'login'
if request.user.is_authenticated:
return redirect('home')
if request.method == 'POST':
email = request.POST.get('email').lower()
password = request.POST.get('password')
try:
user = User.objects.get(email=email)
print(user)
except:
messages.error(request, 'User does not exist.')
user = authenticate(request, email=email, password=password)
if user is not None:
login(request, user)
return redirect('home')
else:
messages.error(request, 'Username or password does not exist.')
context = {'page': page}
return render(request, 'base/login_register.html', context)
def registerPage(request):
form = MyUserCreationForm()
if request.method == 'POST':
form = MyUserCreationForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.username = user.username.lower()
user.save()
login(request, user)
return redirect('home')
else:
messages.error(request, 'An error occured during registration.')
context = {'form': form}
return render(request, 'base/login_register.html', context)
In your User model class you set is_active default value to False
is_active = models.BooleanField(default=False)
So your user is not active when created from registerPage view.
The default backend ModelBackend and RemoteUserBackend prohibits the inactive users from authenticating. Since you are authenticating user from django default authentication it always returns None.
If you want all user's you created to set is_active to True for all users then you can set default to True.
is_active = models.BooleanField(default=True)
Otherwise you can add logic in your views.py to set is_active to True if some condition success
def registerPage(request):
form = MyUserCreationForm()
if request.method == 'POST':
form = MyUserCreationForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.username = user.username.lower()
if active_true_condition: #<--- if condition true set True
user.is_active = True
user.save()
login(request, user)
return redirect('home')
else:
messages.error(request, 'An error occured during registration.')
context = {'form': form}
return render(request, 'base/login_register.html', context)
And set default to False in this case.
In your User models set:
is_active = models.BooleanField(default=True)
I would like to know if it’s possible to create his own login page (from scratch) without using any Django default login forms because I want to add other fields in addition?
Thanks in advance
You could write your own view, but it's better to just subclass the Django LoginView and change as much as you need, for example:
from django.http import HttpResponseRedirect
from django.contrib.auth.views import LoginView
from django.contrib.auth import login
from .forms import MyCustomLoginForm
class SignInView(LoginView):
form_class = MyCustomLoginForm
template_name = 'path/to/my_template.html'
def form_valid(self, form):
# Form is valid, do whatever you need.
login(self.request, form.get_user())
response = HttpResponseRedirect(self.get_success_url())
return response
forms.py
from django import forms
from django.contrib.auth.forms import AuthenticationForm
class MyCustomLoginForm(AuthenticationForm):
age = forms.IntegerField(label='Age', required=True)
def clean_age(self):
age = self.cleaned_data['age']
# validate age
return age
in this user model, I have declared username field as email. User can't get login using username and password. User have to provide email and password to get login.
my models.py
class UserManager(BaseUserManager):
def create_user(self, email, password=None, active=True, is_staff=False, is_admin=False,is_superuser=False):
if not email:
raise ValueError("Users must have an email address")
if not password:
raise ValueError("Users must have password")
user_obj = self.model(
email=self.normalize_email(email)
)
user_obj.set_password(password)
user_obj.staff = is_staff
user_obj.admin = is_admin
user_obj.active = active
user_obj.superuser = is_superuser
user_obj.save(using=self._db)
return user_obj
def create_superuser(self, email, password=None):
user = self.create_user(
email,
password=password,
is_superuser=True,
is_staff=True,
is_admin=True,
)
return user
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=255, unique=True)
staff = models.BooleanField(default=False)
superuser = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
def _str_(self):
return self.email
#property
def is_staff(self):
return self.staff
#property
def is_superuser(self):
return self.superuser
my views.py
from .models import User
class LoginAPIView(APIView):
def post(self, request):
serializer = LoginSerializers(data=request.data)
if serializer.is_valid():
data = serializer.data
email = data['email']
password = data['password']
user = authenticate(email=email, password=password)
if user is not None:
login(request, user)
token, created = Token.objects.get_or_create(user=user)
return Response({"message": "success", "code": status.HTTP_201_CREATED, "details": serializer.data,
"Token": token.key})
return Response(
{"message": "error", "code": status.HTTP_401_UNAUTHORIZED, "details": ["Invalid credentials"]})
my serializers.py:
class LoginSerializers(serializers.Serializer):
username = serializers.CharField(max_length=255)
password = serializers.CharField(max_length=128)
may be this could help you
I have a user in my database with the login jim#test.com and password jimrox. I'm trying to log him in with this view:
def login(request):
email = request.POST.get("email", "")
password = request.POST.get("password", "")
user = authenticate(username=email, password=password)
My custom authentication looks partly like this:
class login(object):
def authenticate(self, username=None, password=None):
# auth user based on email
try:
user = Freelancer.objects.get(email=username)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
When the user attempts to check_password() it doesn't return the user even though the password is correct. Am I meant to create my own check_password() function in the model?
Here is my model also:
class FreelancerManager(BaseUserManager):
def create_user(self, email, date_of_birth, password=None):
"""
Creates and saves a User with the given email, date of
birth and password.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
date_of_birth=date_of_birth,
)
user.set_password(password)
user.save(using=self._db)
return user
class Freelancer(AbstractBaseUser):
email = models.EmailField()
first_name = models.CharField(max_length=128, primary_key=True)
surname = models.CharField(max_length=128)
university = models.CharField(max_length=256)
verified = models.BooleanField(default=False)
created_date = models.DateTimeField(default=timezone.now)
USERNAME_FIELD = 'email'
If I am meant to create my own password check, how would I do that? This is with 1.8 also.
EDIT
Here is how I add my users to the database:
views.py
def freelancer_signup(request):
if request.method == 'POST':
form = FreelancerForm(request.POST)
if form.is_valid():
freelancer = form.save(commit=False)
freelancer.save()
return render(request, 'freelancestudent/index.html')
else:
return render(request, 'freelancestudent/index.html')
else:
form = FreelancerForm()
return render(request, 'freelancestudent/freelancersignup.html', {'form': form})
forms.py
from django import forms
from models import Freelancer
class FreelancerForm(forms.ModelForm):
class Meta:
model = Freelancer
password = forms.CharField(widget=forms.PasswordInput)
fields = ('email', 'first_name', 'surname', 'university', 'password')
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.