so I have this form as on this image below. The point is that if the user clicks any of the fields, the text (which is essentialy a label, not a placeholder) rises up which shows that the clicked input field is active.
However, I've tried to create a customized user creation in Django, which is just to have the email as the main user identificator, not the username. Now everything else works as supposed, but the thing is that the email field always appears as active (you know, the css attribute).
I will now paste a scary amount of code and I will be happy if you could find out what's wrong. Sorry for the trouble
`class UserManager(BaseUserManager):
# handles user creation, havent' tested yet
def create_user(self, email, username, password=None):
# creates user with email as their id
if not email:
raise ValueError('Users must have an email address')
if not username:
raise ValueError('Users must have an username')
if not password:
raise ValueError('Users must have a password')
user = self.model(
email=self.normalize_email(email),
password=password,
username=username,
)
user.set_password(password)
user.save(user=self._db)
return user
class User(AbstractBaseUser):
# user model, was just trying out some stuff
username = models.CharField(verbose_name='username', max_length=30)
email = models.EmailField(verbose_name='email', unique=True,
max_length=60)
date_joined = models.DateTimeField(verbose_name='date joined',
auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login',
auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'email', 'password']
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True`
Now the form part
class RegisterForm(UserCreationForm):
# form to create a new user
class Meta:
model = User
fields = ('username', 'email)'
And the view part
class RegisterView(FormView):
# registration form
form_class = RegisterForm
template_name = 'register.html'
def post(self, request):
form = RegisterForm(request.POST)
if form.is_valid():
print('yes')
return redirect('login')
return render(request, 'register.html', {'form': form})
Again, I am so so sorry for the vaste amount of code, it's just that I'm lost and since I'm just learning this stuff it's hard for me to spot the error.
Thank you so much for any feedback
Related
Tysm in advance, for helping
Already a superuser is made but admin login or login view is not working, Some problem in authenticate it every time returns none if correct password and email are passed
Custom User Model
class UserManager(BaseUserManager):
def create_user(self, email, username, password=None):
if not email:
raise ValueError("Email Requierd!")
if not username:
raise ValueError("Username required!")
user = self.model(
email=self.normalize_email(email),
username=username,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, password):
user = self.create_user(
email=self.normalize_email(email),
password=password,
username=username,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class User(AbstractBaseUser):
userid = models.UUIDField(
default=uuid.uuid4, editable=False, primary_key=True)
username = models.CharField(max_length=255, unique=True)
email = models.EmailField(max_length=255, unique=True)
date_joined = models.DateTimeField(auto_now_add=True)
last_login = models.DateTimeField(auto_now_add=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
#
USERNAME_FIELD = 'email'
#
REQUIRED_FIELDS = ['username']
objects = UserManager()
def __str__(self):
return self.username
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perm(self, app_label):
return True
Already a superuser is made but admin login or login view is not working, Some problem in authenticate it every time returns none if password and email are passed!
psql view
login view
def login_view(request):
user = request.user
if user.is_authenticated:
return redirect('home')
if request.POST:
form = LoginForm(request.POST)
if form.is_valid():
email = request.POST['email']
password = request.POST['password']
user = authenticate(request, email=email, password=password)
if user is not None:
login(request, user)
return redirect('home')
else:
form = LoginForm()
return render(request, 'login.html', {'form': form})
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import get_user_model, authenticate
User = get_user_model()
class UserCreateForm(UserCreationForm):
email = forms.EmailField()
#is_seller = forms.BooleanField
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
class LoginForm(forms.Form):
email = forms.EmailField(required=True)
password = forms.CharField(label='Password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ['email', 'password']
def clean(self):
email = self.cleaned_data['email']
password = self.cleaned_data['password']
if not authenticate(request, email=email, password=password):
raise forms.ValidationError("Invlaid Login")
After login, it doesn't give me any errors and neither redirects to homepage!
After login, it doesn't give me any errors and neither redirects to homepage!
Tysm in advance, for helping
Try to set is_active field as default=True
There are two apps in my ecommerce website and i have been following a particular tutorial on youtube. In the course, the guy used django-allauth package for login purposes. I followed the course along but I created custom user model exending AbstracBaseUser class in account app.
I created another app called product where I handled all the ecommerce logics.
Here's the code:
models.py (account)
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, first_name, last_name, gstin_no, phone_no, password=None):
if not email:
raise ValueError("Users must have an email address")
if not username:
raise ValueError("Users must have a username")
if not first_name:
raise ValueError("Users must have First Name")
if not last_name:
raise ValueError("Users must have Last Name")
if not gstin_no:
raise ValueError("Users must have a valid GSTIN Number")
if not phone_no:
raise ValueError("Users must have a valid Phone Number")
user = self.model(
email=self.normalize_email(email),
username=username,
first_name=first_name,
last_name=last_name,
gstin_no=gstin_no,
phone_no=phone_no,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, first_name, last_name, gstin_no, phone_no, password):
user = self.create_user(
email=self.normalize_email(email),
password=password,
username=username,
first_name=first_name,
last_name=last_name,
gstin_no=gstin_no,
phone_no=phone_no,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
username = models.CharField(max_length=30, unique=True)
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
first_name = models.CharField(verbose_name="first name", max_length=20)
last_name = models.CharField(verbose_name="last name", max_length=20)
gstin_no = models.CharField(verbose_name='gstin no', max_length=15, unique=True)
phone_no = models.BigIntegerField(unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'first_name', 'last_name', 'gstin_no', 'phone_no', ]
objects = MyAccountManager()
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
models.py (product)
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
stripe_customer_id = models.CharField(max_length=50, blank=True, null=True)
one_click_purchasing = models.BooleanField()
def __str__(self):
return self.user.username
def userprofile_receiver(sender, instance, created, *args, **kwargs):
if created:
userprofile = UserProfile.objects.create(user=instance)
post_save.connect(userprofile_receiver, sender=settings.AUTH_USER_MODEL)
views.py (product)
class PaymentView(LoginRequiredMixin, View):
def get(self, *args, **kwargs):
order = Order.objects.get(user=self.request.user, ordered=False)
if order.billing_address:
context = {
'order': order,
'DISPLAY_COUPON_FORM': False
}
userprofile = self.request.user.userprofile
if userprofile.one_click_purchasing:
#fetch the user's card list
cards = stripe.Customer.list_sources(
userprofile.stripe_customer_id,
limit = 3,
object = 'card'
)
card_list = cards['data']
if len(card_list) > 0:
# update the card with the default card
context.update({
'card': card_list[0]
})
return render(self.request, 'product/payment.html', context)
else:
messages.warning(self.request, "You have not added a billing address.")
return redirect("checkout")
The error I am getting is:
RelatedObjectDoesNotExist at /payment/stripe/
Account has no userprofile.
How can I get this working. I am not able to get the concept here about what's wrong.
Go to django admin and check is that userprofile created for that user.If not, Then it is possible you have added user before adding this signal functionality. create new user and check userprofile. If still not created. There is something wrong with your signal.
I'm making a simple django rest framework project.
This is just creating a new user, and logging in.
When I used django basic auth user model, everything worked well.
But after changing basic user model to custom user, this error comes out when creating a new user:
dict object has no attribute 'pk'
Custom user model is made referred to django docs.
Error says that:
File "/home/seokchan/server/mdocker/lib/python3.5/site-packages/django/contrib/auth/__init__.py",
line 100, in login
if _get_user_session_key(request) != user.pk or ( AttributeError: 'dict' object has no attribute 'pk'
This seems to say that user model has no pk, but I don't get it.
models.py
class MyUserManager(BaseUserManager):
def create_user(self, username, email, password=None):
if not email:
raise ValueError('Users must have an email address')
if not username:
raise ValueError('Users must have an user name')
user = self.model(
email=self.normalize_email(email),
username = username
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, username, email, password):
user = self.create_user(
username,
password=password,
email = email,
)
user.is_admin = True
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser):
id = models.AutoField(primary_key=True)
username = models.CharField(
verbose_name='user name',
max_length=30,
unique=True,
)
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
sth_test = models.TextField(blank = True)
objects = MyUserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email']
def __str__(self):
return self.username
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
#property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
serializers.py
class CreateUserSerializer(serializers.ModelSerializer):
class Meta:
model = get_user_model
fields = ('id', 'username', 'email', 'password', 'is_active')
email = serializers.EmailField(
required=True,
validators=[UniqueValidator(queryset=User.objects.all())]
)
username = serializers.CharField(
max_length=32,
validators=[UniqueValidator(queryset=User.objects.all())]
)
password = serializers.CharField(min_length=8, write_only=True)
def validate_email(self,value):
if User.objects.filter(email=value).exists():
raise serializers.ValidationError("err.")
return value
def create(self, validated_data):
user = User.objects.create_user(
validated_data['username'],
validated_data['email'],
validated_data['password'],
)
user.is_active = False
user.save()
message=render_to_string('accounts/account_activate_email.html',{
'user':user,
'domain':'localhost:8000/api/accounts/activate',
'uid':urlsafe_base64_encode(force_bytes(user.pk)).decode('utf-8'),
'token':account_activation_token.make_token(user)
})
mail_subject = 'Bplus'
to_email = user.email
AuthEmail = EmailMessage(mail_subject, message, to=[to_email])
AuthEmail.send()
return validated_data
views.py
class UserCreateAPI(generics.GenericAPIView):
serializer_class = CreateUserSerializer
def post(self, request, *args, **kwargs):
if len(request.data["username"]) < 4 or len(request.data["password"]) < 8:
body = {"message":"short field"}
return Response(body, status = 400)
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.save()
user_for_auth = User.objects.get(username=user['username'])
login(request, user)
return Response(
{
"user":UserSerializer(
user, context=self.get_serializer_context()
).data,
"token":AuthToken.objects.create(user_for_auth),
}
)
How can I fix this error?
Your serializer create method returns the validated data instead of the created object. Since that is a dict, that is what you end up passing to the login function.
You should have return user instead of return validated_data.
I have written a custom form for the creation of a user.
The login works for the users created on the terminal with "python manage.py createsuperuser", but it doesn't work for the users created on the website. I have checked, and the creation form works; I mean, the user is created.
This is the form
class CustomUserCreationForm(UserCreationForm):
"""
A form that creates a user, with no privileges, from the given email and password.
"""
def __init__(self, *args, **kwargs):
super(CustomUserCreationForm, self).__init__(*args, **kwargs)
class Meta:
model = CustomUser
fields = ("email",)
The model
class CustomUser(AbstractBaseUser, PermissionsMixin):
username = models.CharField(max_length=254, unique=True, null=True)
first_name = models.CharField(max_length=254, blank=True)
second_name = models.CharField(max_length=254, blank=True)
email = models.EmailField(blank=True, unique=True)
address1 = models.CharField(max_length=254, blank=True)
address2 = models.CharField(max_length=254, blank=True)
area_code = models.CharField(max_length=20, blank=True)
country_code = models.CharField(max_length=10, blank=True)
date_joined = models.DateTimeField(_('date joined'), default=datetime.now())
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'address1', 'address2', 'area_code', 'country_code']
objects = CustomUserManager()
class Meta:
verbose_name = _('user')
verbose_name_plural = _('users')
def get_absolute_url(self):
return "/users/%s" % urlquote(self.email)
def get_full_name(self):
"""
Returns the first_name plus the last_name, with a space in between.
"""
return full_name.strip()
def get_short_name(self):
"""
Returns the first name for the user.
"""
return self.first_name
def email_user(self, subject, message, from_email=None):
"""
Sends an email to this user.
"""
send_email(subject, message, from_email, [self.email])
The register view
def register(request):
registered = False
if request.method == 'POST':
user_form = CustomUserCreationForm(data=request.POST)
if user_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
registered = True
else:
print user_form.errors
else:
user_form = CustomUserCreationForm()
return render(request, 'register.html', {'user_form': user_form, 'registered': registered})
The login view
def login(request):
if request.method == 'POST':
login_form = CustomUserLoginForm(data=request.POST)
username = request.POST.get('username')
password = request.POST.get('password')
user = auth.authenticate(username=username, password=password)
if user:
if user.is_active:
auth.login(request, user)
return HttpResponseRedirect('/')
else:
return HttpResponse("Your account is disabled.")
else:
print "Invalid login details: {0}, {1}".format(username, password)
return HttpResponse("Invalid login details supplied. Get back to the homepage.")
else:
login_form = CustomUserLoginForm()
return render(request, 'login.html', {'login_form': login_form})
What am I missing here?
Thanks!
First fix the class:
class CustomUser(AbstractUser, PermissionsMixin):
AbstractUser is a real User Model, the BaseUser is just the meta class.
To create a new user you should use this line, in the form or in the register view:
User.objects.create_user(username=username,email=email,password=password)
Note that set_password is used to change the password, and it logs out this user after the password changes.
For almost three days I was trying to overcome same issue. I even wrote AUTHENTICATION_BACKEND. Only after that, a message was displayed on the form that the user is not active. When in save method I assigned True to user.is_active
def save(self):
user = super().save(commit=False)
user.is_active = True
user.save()
This worked for me. I hope it will work for you as well. (Note: I was not aware of rules and posted same message for similar questions to help others as well, when get notice not to do it. If anyone will see my answer for other questions please ignore it. The above answer is edited one and mostly related to this exact issue)
I feel like I'm missing somehting obvious on this one.
I've created a custom user and user manger
class UserManager(BaseUserManager):
# create a normal user
# an email and password must be provided
def create_user(self, email, password, first_name, last_name,
location, date_of_birth):
if not email:
raise ValueError("User must have an email")
if not password:
raise ValueError("User must have a password")
email = email.lower()
user = self.model(
email=email,
first_name=first_name,
last_name=last_name,
location=location,
date_of_birth=date_of_birth
)
user.set_password(password)
user.save(using=self._db)
return user
# Make an administrator
def create_superuser(self, email, password, first_name, last_name,
location, date_of_birth):
user = self.create_user(
email=email,
password=password,
first_name=first_name,
last_name=last_name,
location=location,
date_of_birth=date_of_birth
)
user.is_admin = True
user.is_moderator = True
user.save(using=self._db)
return user
class User(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True
)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
location = models.ForeignKey(Location)
date_of_birth = models.DateField()
date_joined = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
is_moderator = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name', 'location', 'date_of_birth']
def __unicode__(self):
return self.email
def get_full_name(self):
return self.first_name + ' ' + self.last_name
def get_age(self):
age = date.today() - self.date_of_birth
return age.days / 365
def is_staff(self):
return self.is_admin
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
However if I visit the admin site, It will happily authorize a user who is not an admin is_admin=False
Has anyone run into this problem, Is there something I need to change when using django admin with a custom user?
EDIT
setting.py
AUTH_USER_MODEL = 'userAccount.User'
AUTHENTICATION_BACKEND = (
'django.contrib.auth.backends.ModelBackend',
)
is_admin is not something that django's authentication system knows about. In the authentication form that is used, it is only checking if the user is active or is staff:
class AdminAuthenticationForm(AuthenticationForm):
"""
A custom authentication form used in the admin app.
"""
error_messages = {
'invalid_login': _("Please enter the correct %(username)s and password "
"for a staff account. Note that both fields may be "
"case-sensitive."),
}
required_css_class = 'required'
def confirm_login_allowed(self, user):
if not user.is_active or not user.is_staff:
raise forms.ValidationError(
self.error_messages['invalid_login'],
code='invalid_login',
params={'username': self.username_field.verbose_name}
)
In the original user model, is_staff is a model field. You do not have such a field, but rather a method. This could be a why its not working.
You can solve this problem two ways:
Create your own AdminAuthenticationForm and adjust the confirm_login_allowed method to check for is_admin rather than is_staff.
Create a is_staff property in your custom user model:
#property
def is_staff(self):
return self._is_admin