I am using Django in Mac. Last week, the registration is good but now when I rerun it I encountered a problem and I cant seem to figure out where the problem lies. Hope someone can help me. Thank you
error: [19/Sep/2022 20:24:50] "POST /registerUser/ HTTP/1.1" 200 6995
/opt/homebrew/lib/python3.9/site-packages/PIL/Image.py:3011: DecompressionBombWarning: Image size (139513096 pixels) exceeds limit of 89478485 pixels, could be decompression bomb DOS attack.
warnings.warn(
invalid form
<bound method BaseForm.non_field_errors of <
UserForm bound=True, valid=True, fields=(first_name;middle_name;last_name;username;email;mobile_number;password;confirm_password)>>
Views
def registerUser(request):
if request.user.is_authenticated:
messages.warning(request, "You are already logged in!")
return redirect ('myAccount')
elif request.method == 'POST':
form = UserForm(request.POST)
m_form = MemberForm(request.POST, request.FILES)
try:
if form.is_valid() and m_form.is_valid():
first_name = form.cleaned_data['first_name']
middle_name = form.cleaned_data['middle_name']
last_name = form.cleaned_data['last_name']
username = form.cleaned_data['username']
email = form.cleaned_data['email']
mobile_number = form.cleaned_data['mobile_number']
password = form.cleaned_data['password']
user = User.objects.create_user(first_name=first_name, middle_name=middle_name, last_name=last_name, username=username, email=email, mobile_number=mobile_number, password=password)
user.role = User.MEMBER
user.save()
member = m_form.save(commit=False)
member.user = user
member.save()
# send verification email
mail_subject = 'Please Activate Your Account'
email_template = 'accounts/emails/account_verification_email.html'
send_verfication_email(request, user, mail_subject, email_template)
messages.success(request, 'You have signed up successfully! Please check your email to verify your account.')
print(user.password)
return redirect('signin')
except Exception as e:
print('invalid form')
messages.error(request, str(e))
else:
form = UserForm()
m_form = MemberForm()
context = {
'form' : form,
'm_form' : m_form,
}
return render(request, 'accounts/register.html', context)
Model
class UserManager(BaseUserManager):
def create_user(self, first_name, middle_name, last_name, username, email, mobile_number, password=None):
if not email:
raise ValueError('User must have an email address')
if not username:
raise ValueError('User must have an username')
if not mobile_number:
raise ValueError('User must have a mobile number')
user = self.model(
email = self.normalize_email(email), #lowercase email
username = username,
first_name = first_name,
middle_name = middle_name,
last_name = last_name,
mobile_number = mobile_number,
)
user.set_password(password)
user.save(using=self.db)
return user
def create_superuser(self, first_name, middle_name, last_name, username, email, mobile_number, password=None):
user = self.create_user(
email = self.normalize_email(email), #lowercase email
username = username,
password = password,
first_name = first_name,
middle_name = middle_name,
last_name = last_name,
mobile_number = mobile_number,
)
user.is_admin = True
user.is_active = True
user.is_staff = True
user.is_superadmin = True
user.save(using=self.db)
return user
class User(AbstractBaseUser):
MEMBER = 1
ADMIN = 2
SUPERADMIN = 3
ROLE_CHOICE = (
(MEMBER, 'Member'),
(ADMIN, 'Admin'),
(SUPERADMIN, 'Super Admin')
)
ACTIVE = 1
DELETED = 2
DEACTIVATED = 3
STATUS = (
(ACTIVE, 'Active'),
(DELETED, 'Deleted'),
(DEACTIVATED, 'Deactivated')
)
first_name = models.CharField(max_length=50)
middle_name = models.CharField(max_length=50, default="Some String")
last_name = models.CharField(max_length=50)
username = models.CharField(max_length=50, unique=True)
email = models.EmailField(max_length=100, unique=True)
mobile_number = models.CharField(max_length = 100, db_index=True, null = True, validators=[
RegexValidator(
regex='^(\+\d{1,3})?,?\s?\d{8,13}',
message='Phone number must not consist of space and requires country code. eg : +639171234567',
),
])
password = models.CharField(max_length = 100,validators=[MinLengthValidator(8),
])
role = models.PositiveSmallIntegerField(choices=ROLE_CHOICE, blank=True, null=True)
status = models.PositiveSmallIntegerField(choices=STATUS, blank=True, null=True)
# required fields
date_joined = models.DateTimeField(auto_now_add=True)
last_login = models.DateTimeField(auto_now_add=True)
created_date= models.DateTimeField(auto_now_add=True)
modified_date = models.DateTimeField(auto_now_add=True)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
is_superadmin = models.BooleanField(default=False)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email', 'first_name', 'middle_name', 'last_name', 'mobile_number']
objects = UserManager()
def __str__(self):
return self.username
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
def get_role(self):
if self.role == 1:
user_role = 'Member'
elif self.role == 2:
user_role = 'Admin'
elif self.role == 3:
user_role = 'Super Admin'
return user_role
def get_status(self):
if self.status == 1:
user_status = 'Active'
elif self.status == 2:
user_status = 'Deleted'
elif self.status == 3:
user_status = 'Deactivated'
return user_status
class userMember(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
birthdate = models.DateField(blank=True, null=True)
profile_picture = models.ImageField(upload_to='users/profile_pictures', blank=True, null=True)
cover_color = ColorField(format='hexa', blank=True, null=True)
upload_id = models.ImageField(upload_to='member/id')
created_at = models.DateTimeField(auto_now=True)
modified_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.user.username
#receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
userMember.objects.get_or_create(user=instance)
Form
class DateInput(forms.DateInput):
input_type = 'date'
class UserForm(forms.ModelForm):
first_name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Jones', 'style': 'width: 150px; '}))
middle_name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'A', 'style': 'width: 150px; '}))
last_name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Smith', 'style': 'width: 150px; '}))
mobile_number = forms.CharField(max_length=15, validators=[RegexValidator(
'^\+[0-9]{1,3}\.?\s?\d{8,13}', message="Phone number must not consist of space and requires country code. eg : +639171234567")],widget=forms.TextInput(attrs={'placeholder': '09123456789', 'style': 'width: 305px; '}),
error_messages={'unique': ("Mobile Number already exists.")})
email = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'jonesmith#gmail.com', 'style': 'width: 460px; '}),
error_messages={'unique': ("Email already exists.")},)
username = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Jones_Smith31', 'style': 'width: 460px; '}),
error_messages={'unique': ("Username already exists.")},)
password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': '********', 'style': 'width: 460px; '}))
#password = forms.CharField(validators=[MinLengthValidator(8),RegexValidator('^(?=.*[A-Z])(?=.*[!##$&*])(?=.*[0-9])(?=.*[a-z])$', message="Password should be a combination of Alphabets and Numbers")], widget=forms.PasswordInput(attrs={'placeholder': '********', 'style': 'width: 460px; '}))
confirm_password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': '********', 'style': 'width: 460px;' }))
class Meta:
model = User
fields = ['first_name', 'middle_name', 'last_name', 'username', 'email', 'mobile_number', 'password']
def clean(self):
clean_data = super(UserForm, self).clean()
password = clean_data.get('password')
confirm_password = clean_data.get('confirm_password')
if password != confirm_password:
raise forms.ValidationError(
"Password and Confirm Password does not match!"
)
class MemberForm(forms.ModelForm):
birthdate = forms.DateField(widget=DateInput(attrs={'class': 'form-control ', }))
profile_picture = forms.FileField(widget=forms.FileInput(attrs={'class': 'btn btn-info'}))
class Meta:
model = userMember
fields = ['birthdate', 'upload_id', 'profile_picture']
I think pil is protecting you against large files. You can disable it, if you want.
from PIL import Image
Image.MAX_IMAGE_PIXELS = None
Related
for my web-application which is made in Django and I made a custom users app for users (so I am not using the Django's user). I managed to get the users app working and I created a superuser using this command:
python manage.py createsuperuser
and got this message:
Superuser created successfully.
but when I tried to log in as the superuser in the browser, it did not work and got this error message on the browser (I tried different browsers as well):
Please enter the correct username and password for a staff account. Note that both fields may be case-sensitive.
I paid attention to case-sensitive letters. do you know what the problem could be?
here is the models.py for the users app:
import random
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.core import validators
from django.utils import timezone
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager, send_mail
class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, username, password, phone_number, email, is_staff, is_superuser, **extra_fields):
"""
Created and saves a User with the given username, email and password.
"""
now = timezone.now()
if not username:
raise ValueError('The given username must be set')
email = self.normalize_email(email)
user = self.model(phone_number=phone_number,
username=username, email=email,
is_staff=is_staff, is_active=True,
is_superuser=is_superuser,
date_joined=now, **extra_fields)
if not extra_fields.get('no_password'):
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, username=None, phone_number=None, email=None, password=None, **extra_fields):
if username is None:
if email:
username = email.split('#', 1)[0]
if phone_number:
username = random.choice('abcdefghijklmnopqrstuvwxyz') + str(phone_number)[-7:]
while User.objects.filter(username=username).exists():
username += str(random.randint(10, 99))
return self._create_user(username, phone_number, email, password, False, False, **extra_fields)
def create_superuser(self, username, email, phone_number, password, **extra_fields):
return self._create_user(username, email, phone_number, password, True, True, **extra_fields)
def get_by_phone_number(self, phone_number):
return self.get(**{'phone_number': phone_number})
class User(AbstractBaseUser, PermissionsMixin):
username = models.CharField(_('username'), max_length=32, unique=True,
help_text=
'Required. 30 characters or fewer starting with a letter. Letters, digits',
validators=[
validators.RegexValidator(r'^[a-zA-Z][a-zA-Z0-9_\.]+$',
_('Enter a valid username starting with a-z.'
'This value may contain only letters and numbers'
'and underscore characters.'), 'invalid')
],
error_messages={
'unique':_('A user with that username already exists.'),
}
)
first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=30, blank=True)
email = models.EmailField(_('email address'), unique=False, null=True, blank=True)
phone_number = models.BigIntegerField(_('phone number'), unique=True, null=True, blank=True,
validators=[
validators.RegexValidator(r'^319[0-3,9]\d{8}$',
('Enter a valid mobile number.'), 'egrwfk')
],
error_messages={
'unique': _('A user with this mobile phone number already exits')
}
)
is_staff = models.BooleanField(_('staff status'), default=False,
help_text='designates whether this user can log into this admin site.')
is_active = models.BooleanField(_('active'), default=True,
help_text=_('designates whether this user should be treated as active'))
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
last_seen = models.DateTimeField(_('last seen date'), null=True)
objects = UserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email', 'phone_number']
class Meta:
db_table = 'users'
verbose_name = _('user')
verbose_name_plural = _('users')
def get_full_name(self):
full_name = '%s %s' % (self.first_name, self.last_name)
return full_name.strip()
def get_short_name(self):
return self.first_name
def email_user(self, subject, message, from_email=None, **kwargs):
send_mail(subject, message, from_email, [self.email], **kwargs)
#property
def is_loggedin_user(self):
return self.phone_number is not None or self.email is not None
def save(self, *args, **kwargs):
if self.email is not None and self.email.strip() == '':
self.email = None
super().save(*args, **kwargs)
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
nick_name = models.CharField(_('nick_name'), max_length=150, blank=True)
avatar = models.ImageField(_('avatar'), blank=True)
birthday = models.DateField(_('birthday'), null=True, blank=True)
gender = models.BooleanField(_('gender'), null=True, help_text='femal is False, male is True, null is unset')
province = models.ForeignKey(verbose_name=_('province'), to='Province', null=True, on_delete=models.SET_NULL)
# email = models.EmailField(_('email_address'), blank=True)
# phone_number = models.BigIntegerField(_('phone_number'), null=True, blank=True,
# validators=[
# validators=RegexValidators(r'^319[0-3,9]\d(8)$,
# _('Enter a valid mobile number'), 'invalid'),
# ],
# )
class Meta:
db_table = 'user_profiles'
verbose_name = _('profile')
verbose_name_plural = _('profiles')
#property
def get_first_name(self):
return self.user.first_name
#property
def get_last_name(self):
return self.user.last_name
def get_nick_name(self):
return self.nick_name if self.nick_name else self.user.username
class Device(models.Model):
WEB = 1
IOS = 2
ANDROID = 3
DEVICE_TYPE_CHOICES = (
(WEB, 'web'),
(IOS, 'ios'),
(ANDROID, 'android')
)
user = models.ForeignKey(User, related_name='devices', on_delete=models.CASCADE)
device_uuid = models.UUIDField(_('Device UUID'), null=True)
# notify_token = models.CharField(_('notification token'), max_length=200, blank=True,
# validators=[validators.RegexValidator(r'([a-z]|[A-z]|[0-9])\w+',
# _('Notify token is not valid'), 'invalid')]
# )
last_login = models.DateTimeField(choices=DEVICE_TYPE_CHOICES, default=ANDROID)
device_type = models.PositiveSmallIntegerField(choices=DEVICE_TYPE_CHOICES, default=ANDROID)
device_os = models.CharField(_('device os'), max_length=20, blank=True)
device_model = models.CharField(_('device model'), max_length=50, blank=True)
app_version = models.CharField(_('app version'), max_length=20, blank=True)
created_time = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'user_devices'
verbose_name = _('device')
verbose_name_plural = _('devices')
unique_together = ('user', 'device_uuid',)
class Province(models.Model):
name = models.CharField(max_length=50)
is_valid = models.BooleanField(default=True)
modified_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
I am also getting this message on the terminal:
[05/Jan/2023 13:38:44] "POST /admin/login/?next=/admin/ HTTP/1.1" 200 2374
I've created a custom user model, subclassing AbstractUser.
I have a registration view, template, and a CustomUserCreationForm that seems to work fine, and can register users no problem via the front end.
My issue is getting the user logged in. I can't seem to pass the form validation to authenticate them with. I'm always returned with a None user object
With this line for example, I always get None, this failing verification
user = authenticate(request, email=email, password=password)
# user = User.objects.get(email=email, password=hashed_pass)
# Check if authentication successful
if user is not None:
login(request, user)
return HttpResponseRedirect(reverse("clientcare:portal/dashboard"))
else:
return render(request, "clientcare/login.html", {
"message": "Invalid email and/or password.",
'login_form':LoginForm,
})
Forms
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = User
fields = ('email', 'first_name','last_name' ,'city', 'province','age','gender','phone_number','password1', 'password2',)
class LoginForm(forms.Form):
email = forms.EmailField(max_length=100)
password = forms.CharField(widget = forms.PasswordInput())
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = User
fields = ('email', 'first_name','last_name' ,'city', 'province','age','gender','phone_number',)
Models
# Create your models here.
class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, email, password, **extra_fields):
if not email:
raise ValueError('Users require an email field')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, password=None, **extra_fields):
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
extra_fields.setdefault('is_patient', False)
extra_fields.setdefault('is_provider', True)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', 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 User(AbstractUser):
username = None
email = models.EmailField(_('email address'), unique=True)
image_height = models.PositiveIntegerField(null=True, blank=True, editable=False, default="200")
image_width = models.PositiveIntegerField(null=True, blank=True, editable=False, default="200")
date_joined = models.DateTimeField(auto_now=True, null=False, blank=False)
city = models.CharField(null=False, blank=False, max_length=20)
province = models.CharField(null=False, blank=False, max_length=20)
profile_image_url = models.ImageField(null=True, blank=True, upload_to='images/', editable=True)
paid = models.BooleanField(default=False)
phone_number = PhoneField(blank=True, null=True, help_text='Contact phone number', E164_only=False)
in_trial = models.BooleanField(default=True)
recently_active = models.BooleanField(default=True)
gender = models.CharField(choices=(("Male", "Male"),("Female", "Female"), ("Other", "Other")), max_length=6, default="Male", null=False, blank=False)
age = models.SmallIntegerField(max_length=3,null=False, blank=False)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name',]
# classify if the user is a provider or a patient
is_patient = models.BooleanField('Patient status',default=False)
is_provider = models.BooleanField('Provider status',default=False)
def __str__(self):
return f"{self.get_full_name()}"
Login View
def login_view(request):
if request.method == "POST":
login_form = LoginForm(data=request.POST)
if login_form.is_valid():
email = login_form.cleaned_data['email']
password = login_form.cleaned_data['password']
# hashed_pass = bcrypt.hashpw(raw_pass, salt)
# if bcrypt.checkpw(raw_pass, hashed_pass):
user = authenticate(request, email=email, password=password)
# user = User.objects.get(email=email, password=hashed_pass)
# Check if authentication successful
if user is not None:
login(request, user)
return HttpResponseRedirect(reverse("clientcare:portal/dashboard"))
else:
return render(request, "clientcare/login.html", {
"message": "Invalid email and/or password.",
'login_form':LoginForm,
})
else:
return render(request, "clientcare/login.html", {
"message": "Invalid login data. Please try again",
'login_form':LoginForm,
})
else:
return render(request, "clientcare/login.html", {
'login_form':LoginForm,
})
Registration view
def register(request):
# Adding the salt to password
if request.method == "POST":
register_form = CustomUserCreationForm(request.POST)
if register_form.is_valid():
email = register_form.cleaned_data['email']
city = register_form.cleaned_data["city"]
province = register_form.cleaned_data["province"]
first_name = register_form.cleaned_data["first_name"]
last_name = register_form.cleaned_data["last_name"]
phone_number = register_form.cleaned_data["phone_number"]
age = register_form.cleaned_data["age"]
gender = register_form.cleaned_data["gender"]
# Ensure password matches confirmation
password = register_form.cleaned_data["password1"]
confirmation = register_form.cleaned_data["password2"]
if password != confirmation:
return render(request, "clientcare/register.html", {
"messsage": "Passwords must match."
})
# Hashing the password
# hashed = bcrypt.hashpw(password, salt)
# password = hashed
# Attempt to create new user
try:
user = User.objects.create(email=email, city=city, province=province, password=password, first_name=first_name, last_name=last_name, phone_number=phone_number, age=age, gender=gender)
user.save()
except IntegrityError:
return render(request, "clientcare/register.html", {
"message": "ERROR. TRY AGAIN",
})
login(request, user)
return HttpResponseRedirect(reverse("clientcare:index"))
else:
return render(request, "clientcare/register.html", {
"message": "ERROR. PLEASE CONFIRM REGISTRATION INFO",
})
else:
return render(request, "clientcare/register.html",{
'registration_form':CustomUserCreationForm
})
I have my user in settings.py as such:
AUTH_USER_MODEL = 'clientcare.User'
I'm well aware I can use AllAuth or other auth libraries. But I'm trying to understand things on a lower level before using such libraries.
Any help would be appreciated.
Nothing I try seems to work in getting my custom user model logged in. Do I need to write a custom backend? AuthenticationForm doesn't seem to work just as my own login form doesn't seem to validate
HOWEVER, if I update a users password via the admin(with superuser), then the user can login no problem with the updated password.. so my CustomUserChangeForm does the job. What am I missing?
I'm putting a model of my old project here as an example. Here I used the user model as it is and added the fields I wanted to add to the new class that user is also a field there. Django's auth module works as is and no additional coding was required.
from django.contrib.auth.models import User
from django.db import models
from django.utils.translation import ugettext_lazy as _
from backend.custom_fields import AutoOneToOneField
from backend import definitions
from django.urls import reverse
from django.db.models.signals import post_save
from django.dispatch import receiver
from backend.convert import convert_string_to_url_safe
from random import randint
from backend.image_operation import image_resize, image_convert_to_jpg
EMAIL_PRIVACY_CHOICES = (
(0, _('Display your e-mail address.')),
(1, _('Hide your e-mail address but allow form e-mail.')),
(2, _('Hide your e-mail address and disallow form e-mail.')),
)
PHONE_PRIVACY_CHOICES = (
(0, _('Display your phone no.')),
(1, _('Hide your phone no.')),
)
def avatar_upload_file_name_path(instance, filename_ext):
ext = filename_ext.split('.')[-1]
return f'profile_uploads/{convert_string_to_url_safe(instance.get_full_name)}-{randint(1000, 10000)}.{ext}'
def photo_upload_file_name_path(instance, filename_ext):
ext = filename_ext.split('.')[-1]
return f'profile_uploads/{convert_string_to_url_safe(instance.get_full_name)}-{randint(1000, 10000)}.{ext}'
def resized_photo_upload_file_name_path(instance, filename_ext):
ext = filename_ext.split('.')[-1]
return f'profile_uploads/resized-{convert_string_to_url_safe(instance.get_full_name)}-{randint(1000, 10000)}.{ext}'
class PlatformUser(models.Model):
user = AutoOneToOneField(User, on_delete=models.CASCADE)
slug = models.CharField(max_length=100, null=True, blank=True)
title = models.CharField(max_length=60, blank=True, default='')
description = models.TextField(blank=True, default='')
phone = models.CharField(max_length=25, blank=True, default='')
facebook_address = models.URLField(blank=True, default='')
twitter_address = models.URLField(blank=True, default='')
instagram_address = models.URLField(blank=True, default='')
linkedin_address = models.URLField(blank=True, default='')
youtube_address = models.URLField(blank=True, default='')
site = models.URLField(_('Personal Site'), blank=True)
skype_name = models.CharField(_('Skype Name'), max_length=100, blank=True, default='')
birth_date = models.DateTimeField(_('Birth Date'), blank=True, null=True)
location = models.CharField(_('Location'), max_length=30, blank=True)
photo = models.ImageField(upload_to=photo_upload_file_name_path, blank=True, default='')
photo_resized = models.ImageField(upload_to=resized_photo_upload_file_name_path, blank=True, null=True)
show_photo = models.BooleanField(_('Show avatar'), blank=True, default=True)
show_signatures = models.BooleanField(_('Show signatures'), blank=True, default=True)
show_smilies = models.BooleanField(_('Show smilies'), blank=True, default=True)
email_privacy_permission = models.IntegerField(_('Privacy permission'), choices=EMAIL_PRIVACY_CHOICES, default=1)
phone_privacy_permission = models.IntegerField(_('Privacy permission'), choices=PHONE_PRIVACY_CHOICES, default=1)
auto_subscribe = models.BooleanField(_('Auto subscribe'),
help_text=_("Auto subscribe all topics you have created or reply."),
blank=True, default=False)
post_count = models.IntegerField(_('Post count'), blank=True, default=0)
likes_count = models.IntegerField(default=0)
view_count = models.IntegerField(default=0)
signature = models.TextField(_('Sign'), blank=True, default='', max_length=definitions.SIGNATURE_MAX_LENGTH)
signature_html = models.TextField(_('Sign as HTML'), blank=True, default='',
max_length=definitions.SIGNATURE_MAX_LENGTH)
verification_code = models.CharField(_('Verify Code'), blank=True, default='', max_length=40)
created = models.DateTimeField(_('Created'), auto_now_add=True)
updated = models.DateTimeField(_('Updated'), auto_now=True, null=True)
class Meta:
ordering = ['user']
get_latest_by = 'created'
verbose_name = _('Platform Member')
verbose_name_plural = _('Platform Members')
def __init__(self, *args, **kwargs):
super(PlatformUser, self).__init__(*args, **kwargs)
self.__original_image_filename = self.photo.name
#property
def email(self):
return self.user.email
#property
def get_full_name(self):
full_name = str(self.user.first_name.title())
if len(full_name) > 0:
full_name += " "
full_name += str(self.user.last_name.title())
if len(full_name) == 0:
full_name = self.user.username
return full_name
#property
def username(self):
return self.user.username
#property
def first_name(self):
return self.user.first_name
#property
def last_name(self):
return self.user.last_name
def __str__(self):
return f"[{self.user.first_name} {self.user.last_name}] - ({self.user.email})"
def get_absolute_url(self):
return reverse('profile',
args=[str(self.get_slug())])
def get_slug(self):
if not self.slug:
self.slug = self.user.username
return self.slug
def save(self, *args, **kwargs):
if not self.slug:
self.slug = self.get_slug()
if self.photo and (self.photo.name != self.__original_image_filename or not self.photo_resized):
self.photo_resized = image_resize(400, 400, self.photo)
self.photo = image_convert_to_jpg(self.photo)
super(PlatformUser, self).save(*args, **kwargs)
#receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
PlatformUser.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
platform_users = PlatformUser.objects.filter(user=instance)
if len(platform_users) > 0:
platform_user = platform_users[0]
else:
platform_user = PlatformUser.objects.create(user=instance)
platform_user.save()
as you could see there are receivers for creating my own platform user row on database when user created.
This way is simple but useful in my opinion. Your way is more correct but more complex.
BTW I dont use and dont like django forms at all.
Solved. I realized I wasn't using the create_user method I wrote in my registration view.
Updated the line below:
user = User.objects.create_user(email=email, city=city, province=province, password=password, first_name=first_name, last_name=last_name, phone_number=phone_number, age=age, gender=gender)
After this, my login form and validation worked. So for anyone having a similar issue, make sure you're using the create_user method if you wrote one/if you're using a custom user model/if you call user.set_password(password) in that method and not in your view.
I am using Django and editing the user page. When I press submit, it does not push thru. There was no error found and cannot locate where the problem lies. Hope someone can help me or point out my mistake.
The user profile page only contains first_name, middle_name, last_name, mobile_number, username and email. It does not contain, password. Thank you
Forms.py
class UserManagementForm(forms.ModelForm):
class Meta:
model = User
fields = ['first_name', 'middle_name', 'last_name', 'username', 'email', 'mobile_number', 'password']
ROLE_CHOICE = (
(2, 'Admin'),
(3, 'Super Admin')
)
ROLE_CHOICE_1 = (
(1, 'Member'),
(2, 'Admin'),
(3, 'Super Admin')
)
first_name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Jones', 'class': 'form-control ', }))
middle_name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'A', 'class': 'form-control', }))
last_name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Smith', 'class': 'form-control',}))
mobile_number = forms.CharField(max_length=15, validators=[RegexValidator(
'^\+[0-9]{1,3}\.?\s?\d{8,13}', message="Phone number must not consist of space and requires country code. eg : +639171234567")],widget=forms.TextInput(attrs={'placeholder': '09123456789', 'class': 'form-control',}),
error_messages={'unique': ("Mobile Number already exists.")})
email = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'jonesmith#gmail.com', 'class': 'form-control',}),
error_messages={'unique': ("Email already exists.")},)
username = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control',}),
error_messages={'unique': ("Username already exists.")},)
password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control',}))
confirm_password = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': '********', 'class': 'form-control', }))
role = forms.CharField(widget=forms.Select(choices=ROLE_CHOICE, attrs={ 'class': 'form-control', }))
def __init__(self, *args, **kwargs):
ROLE_CHOICE_1 = (
(1, 'Member'),
(2, 'Admin'),
(3, 'Super Admin')
)
super(UserManagementForm, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
if instance and instance.pk:
self.fields['role'].widget.choices = ROLE_CHOICE_1
def clean(self):
clean_data = super(UserManagementForm, self).clean()
password = clean_data.get('password')
confirm_password = clean_data.get('confirm_password')
if password != confirm_password:
raise forms.ValidationError(
"Password and Confirm Password does not match!"
)
def save(self, commit=True):
user = super(UserManagementForm, self).save(commit=False)
password = self.cleaned_data["password"]
if password:
user.set_password(password)
if commit:
user.save()
return user
Models.py
class User(AbstractBaseUser):
MEMBER = 1
ADMIN = 2
SUPERADMIN = 3
ROLE_CHOICE = (
(MEMBER, 'Member'),
(ADMIN, 'Admin'),
(SUPERADMIN, 'Super Admin')
)
ACTIVE = 1
DELETED = 2
DEACTIVATED = 3
STATUS = (
(ACTIVE, 'Active'),
(DELETED, 'Deleted'),
(DEACTIVATED, 'Deactivated')
)
first_name = models.CharField(max_length=50)
middle_name = models.CharField(max_length=50, default="Some String")
last_name = models.CharField(max_length=50)
username = models.CharField(max_length=50, unique=True)
email = models.EmailField(max_length=100, unique=True)
mobile_number = models.CharField(max_length = 100, db_index=True, null = True, validators=[
RegexValidator(
regex='^(\+\d{1,3})?,?\s?\d{8,13}',
message='Phone number must not consist of space and requires country code. eg : +639171234567',
),
])
password = models.CharField(max_length = 100,validators=[MinLengthValidator(8),
])
role = models.PositiveSmallIntegerField(choices=ROLE_CHOICE, blank=True, null=True)
status = models.PositiveSmallIntegerField(choices=STATUS, blank=True, null=True)
# required fields
date_joined = models.DateTimeField(auto_now_add=True)
last_login = models.DateTimeField(auto_now_add=True)
created_date= models.DateTimeField(auto_now_add=True)
modified_date = models.DateTimeField(auto_now_add=True)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
is_superadmin = models.BooleanField(default=False)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email', 'first_name', 'middle_name', 'last_name', 'mobile_number']
Views.py
def super_user_account_edit(request, id=None):
user = get_object_or_404(User, pk=id)
if request.method == 'POST':
form = UserManagementForm(request.POST, instance=user)
if form.is_valid():
form.save()
messages.success(request, 'Category updated successfully!')
return redirect('super_user_account')
else:
print(form.errors)
else:
form = UserManagementForm(instance=user)
context = {
'form': form,
'user': user,
}
return render(request, 'pages/super_user_account_edit.html', context)
You might need to add the line {{ form.non_field_errors }} (docs) to the form in your template. This is because if a validation error occurs that is not tied to a specific field, it is only displayed if you include that line.
I’m really new in Django and I would like to create a register form to login user.
I would like this form have additional and required fields. the problem is when I try to fill the sign up registration directly on the web, the user is not registered, but if I do it in /admin section, the user is saved, so I have used custom user
So first I have created class in model.py file:
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(max_length=30)
last_name = models.CharField(max_length=30)
phone_regex = RegexValidator(
regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.")
phone_number = models.CharField(
validators=[phone_regex], max_length=17, blank=True) # validators should be a list
role = models.CharField(max_length=50)
store = models.CharField(max_length=50)
aisle = models.CharField(max_length=50, unique=True)
user_identification = models.CharField(max_length=30, unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'first_name', 'last_name',
'phone_number', 'role', 'store', 'aisle', 'user_identification']
objects = MyAccountManager()
def __str__(self):
return self.email
# if user is admin, can chenge
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
#property
def staff(self):
return self.is_staff
#property
def active(self):
return self.is_active
after I have created the Account Manager in the same models.py
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, first_name, last_name,
phone_number, role, store, aisle, user_identification, password=None):
if not email:
raise ValueError("Users must have an email address")
if not username:
raise ValueError("Users must have an user name")
if not first_name:
raise ValueError("Users must have an user name")
if not last_name:
raise ValueError("Users must have an user name")
if not phone_number:
raise ValueError("Users must have an user name")
if not role:
raise ValueError("Users must have an user name")
if not store:
raise ValueError("Users must have an user name")
if not aisle:
raise ValueError("Users must have an user name")
if not user_identification:
raise ValueError("Users must have an user name")
user = self.model(
email=self.normalize_email(email),
username=username,
first_name=first_name,
last_name=last_name,
phone_number=phone_number,
role=role,
store=store,
aisle=aisle,
user_identification=user_identification,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, first_name, last_name,
phone_number, role, store, aisle, user_identification, password=None):
user = self.create_user(
email=self.normalize_email(email),
username=username,
first_name=first_name,
last_name=last_name,
phone_number=phone_number,
role=role,
store=store,
aisle=aisle,
user_identification=user_identification,
password=password,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
then in the forms.py file I have created the register method:
class RegistrationForm(UserCreationForm):
email = forms.EmailField(
max_length=60, help_text='Required. Add a valid email address')
first_name = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30)
phone_number = forms.CharField(max_length=30)
role = forms.CharField(max_length=30)
aisle = forms.CharField(max_length=30)
user_identification = forms.CharField(max_length=30)
class Meta:
model = Account
fields = ["email", "username", "password1", "password2", 'first_name', 'last_name',
'phone_number', 'role', 'store', 'aisle', 'user_identification', ]
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(RegistrationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.phone_number = self.cleaned_data['phone_number']
user.role = self.cleaned_data['role']
user.aisle = self.cleaned_data['aisle']
user.user_identification = self.cleaned_data['user_identification']
if commit:
user.save()
return user
and the view looks like that:
def registration_view(request): # request, GET from the web
form = RegistrationForm()
context = {}
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
email = form.cleaned_data.get('email')
raw_password = form.cleaned_data.get('password1')
account = authenticate(email=email, password=raw_password)
# name = form.cleaned_data.get('email')
login(request, account)
return redirect('home')
else:
context['registration_form'] = form
else:
form = RegistrationForm()
context['registration_form'] = form
# here we inflate and return the view
return render(request, 'account/register.html', context)
I have configured in settings.py the user custom model:
AUTH_USER_MODEL = 'account.Account'
Also I have configured the admin.py file
class AccountAdmin (UserAdmin):
list_display = ('email', 'username', 'date_joined',
'last_login', 'is_admin', 'is_staff',)
search_fields = ('email', 'username',)
readonly_fields = ('date_joined', 'last_login')
filter_horizontal = ()
list_filter = ()
fieldsets = ()
admin.site.register(Account, AccountAdmin)
admin.site.register(UserProfile)
thanks a lot for your help guys!
Perhaps are you always setting commit=false in order to work with it before saving, but then always is going to avoid saving because the if sentence at the end of the Def ?
class RegistrationForm(UserCreationForm):
...
def save(self, commit=True):
user = super(RegistrationForm, self).save(**commit=False**)
user.set_password(self.cleaned_data["password1"])
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.phone_number = self.cleaned_data['phone_number']
user.role = self.cleaned_data['role']
user.aisle = self.cleaned_data['aisle']
user.user_identification = self.cleaned_data['user_identification']
**if commit:**
user.save()
return user
I hope this helps!
I'm making a custom user model in django, but somehow any new users created through the creation form is missing their assigned permissions (is_active, is_staff, is_admin), preventing them from logging in at all.
Can anyone show me where did I go wrong? Any suggestion is greatly appreciated!
Code snippets:
models.py
class MyUserManager(BaseUserManager):
use_in_migrations = True
def create_user(self, ID, name, email, privilege, password=None):
if not ID:
raise ValueError('Users must have a ID number')
user = self.model(
ID=ID,
name=name,
email=self.normalize_email(email),
privilege=privilege,
)
if self.privilege == 'Admin':
self.is_superuser = True
else:
user.is_active = True
user.is_staff = False
user.is_admin = False
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, NIP, name, email, privilege, password):
new_user = self.create_user(
ID,
name,
email,
privilege,
password=password,
)
new_user.is_superuser = True
new_user.save(using=self._db)
return new_user
class employee(AbstractBaseUser, PermissionsMixin):
ID = models.IntegerField(verbose_name="ID", unique=True)
name = models.CharField(verbose_name="Name", max_length=50, blank=True, unique=True)
email = models.EmailField(verbose_name="email", max_length=225, default='this#mail.com')
Department = models.CharField(max_length=50, choices=DEP_CHOICES, default='')
Role = models.CharField(max_length=50, choices=ROLE_CHOICES, default='')
privilege = models.CharField(max_length=10, default='User')
is_admin = models.BooleanField()
is_staff = models.BooleanField()
is_active = models.BooleanField()
forms.py
class CustomUserCreationForm(UserCreationForm):
ID = forms.CharField(max_length=50)
password = forms.CharField(widget=forms.PasswordInput)
class Meta(UserCreationForm):
model = employee
fields = "__all__"
class CustomUserChangeForm(UserChangeForm):
ID = forms.CharField(max_length=50)
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = employee
fields = "__all__"
admin.py
class UserAdmin(BaseUserAdmin):
# The forms to add and change user instances
add_form = CustomUserChangeForm
form = CustomUserChangeForm
model = employee
list_display = ('ID', 'name', 'email', 'privilege')
list_filter = ('is_admin',)
fieldsets = (
(None, {'fields': ('ID', 'password')}),
('Personal info', {'fields': ('name', 'email', 'privilege')}),
('Permissions', {'fields': ('is_admin', 'is_staff', 'is_active')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('ID', 'name', 'email')}
),
)
search_fields = ('name',)
ordering = ('ID',)
filter_horizontal = ()
views.py
def employee_list(request):
data_list = Employee.objects.order_by('NIP')
registered = False
if request.method == "POST":
if 'add_user' in request.POST:
user_form = CustomUserCreationForm(request.POST, prefix='add')
if user_form.is_valid():
new_user = user_form.save()
new_user.set_password(user.password)
new_user.save()
registered = True
return HttpResponseRedirect(reverse('employee'))
else:
user_form = CustomUserCreationForm(prefix='add')
return render(request, 'employee_list.html',
{'SignUpForm': user_form,
'registered': registered,
'Emp_list':data_list})
Instead of using 'priviledge' as a character field in the Employee model, which is very prone to error in user input, use a choice field instead.
class MyUserManager(BaseUserManager):
use_in_migrations = True
def create_user(self, name, email, privilege='member', is_admin=False, is_staff=False, password=None):
if not email:
raise ValueError('Users must have an email address')
user = self.model(
name=name,
email=self.normalize_email(email),
privilege=privilege,
)
user.set_password(password)
user.is_active = True
user.is_staff = is_staff
user.is_admin = is_admin
user.save(using=self._db)
return user
def create_superuser(self, name, email, password):
new_user = self.create_user(
name,
email,
privilege='admin',
password=password,
is_staff=True,
is_admin=True
)
return new_user
class Employee(AbstractBaseUser):
PRIVILEGE_LEVEL = (
('Administrator', 'admin'),
('Staff', 'staff'),
('Member', 'member'),
)
# ID = models.IntegerField(verbose_name="ID", unique=True)
id = models.AutoField(primary_key=True)
name = models.CharField(verbose_name="Name", max_length=50, blank=True, unique=True)
email = models.EmailField(verbose_name="email", max_length=225, default='this#mail.com')
Department = models.CharField(max_length=50, choices=DEP_CHOICES, default='')
Role = models.CharField(max_length=50, choices=ROLE_CHOICES, default='')
# privilege = models.CharField(max_length=10, default='User')
privilege = models.CharField(max_length=120, choices=PRIVILEGE_LEVEL, default='member')
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
Also, 'id' is auto generated by django as the primary key field, so it doesnt have to be in the frontend form.
By default the django model form calls MyUserManager.create_user.
and based on the modifications i made above, it defaults to creating a user
without permissions. Unless is_admin and is_staff are implicitly set to True
To create a superuser from your current form, you can update MyUserManager.create_user like so,
def create_user(self, name, email, privilege='member', is_admin=False, is_staff=False, password=None):
if not email:
raise ValueError('Users must have an email address')
user = self.model(
name=name,
email=self.normalize_email(email),
privilege=privilege,
)
user.set_password(password)
user.is_active = True
user.is_staff = is_staff
user.is_admin = is_admin
if privilege == 'admin':
user.is_superuser = True
user.save(using=self._db)
return user
But i would advise you update your CustomUserCreationForm instead as such,
class CustomUserCreationForm(UserCreationForm):
# ID = forms.CharField(max_length=50)
password = forms.CharField(widget=forms.PasswordInput)
class Meta(UserCreationForm):
model = Employee
fields = "__all__"
# ADD THIS
def clean(self, value):
print(self.data)
print(self.errors)
cleaned_data = self.cleaned_data
print(cleaned_data)
return cleaned_data
# ADD THIS
def save(self, *args, **kwargs):
data = self.cleaned_data
# email, password1 = v['email'], v['password1']
employee = None
if data['privilege'] == 'admin':
employee = Employee.objects.create_superuser(
name=data['name'],
email=data['email'],
password=data['password'],
)
else:
employee = Employee.objects.create_user(
name=data['name'],
email=data['email'],
password=data['password'],
)
# User is already saved after calling BaseUserManager function.
return employee
MyUserManager.create_superuser calls the MyUserManager.create_user and updates it based on parameter passed to it.
Let me know if you need further clarifications. Cheers.