I was working on my project and i found a bug in my AbstractUser Model. I have certain fields set to null=True and i realized that whenever i create a user, those field do not return null to database.
Here is my AbstractUser Model
class User(AbstractUser):
username = models.CharField(max_length=9, default="", unique=True)
avatar = models.ImageField(
blank=True,
null=True,
default="avatar.png",
upload_to="images",
validators=[validate_pic_extension],
)
password2 = models.CharField(
default=None,
max_length=128,
verbose_name="Confirm Password",
null=True,
blank=True,
)
email = models.EmailField(default=None, max_length=255, unique=True)
designation = models.CharField(
default="Student", choices=DESIGNATION, max_length=255, null=True, blank=True
)
staff_id = models.CharField(
default=None,
max_length=255,
null=True,
blank=True,
verbose_name="Staff Id",
)
matric_no = models.CharField(
default=None,
max_length=255,
null=True,
blank=True,
verbose_name="Matric Number",
)
lib_user = models.CharField(
default=None,
max_length=255,
choices=LIBUSER,
null=True,
blank=True,
verbose_name="Library User",
)
library_id = models.CharField(
default=None,
max_length=255,
null=True,
blank=True,
verbose_name="Library Card Id",
)
def __str__(self):
return self.username
views.py
def signup(request):
if request.method == "POST":
form = Signup(request.POST)
if form.is_valid():
username = request.POST.get("username")
first_name = request.POST.get("first_name")
last_name = request.POST.get("last_name")
email = request.POST.get("email")
password = request.POST.get("password")
password2 = request.POST.get("password2")
staff_id = request.POST.get("staff_id")
matric_no = request.POST.get("matric_no")
library_id = request.POST.get("library_id")
designation = request.POST.get("designation")
lib_user = request.POST.get("lib_user")
user = User.objects.create_user(
username=username.lower(),
first_name=first_name.lower(),
last_name=last_name.lower(),
password=password,
email=email,
staff_id=staff_id,
matric_no=matric_no,
library_id=library_id,
designation=designation,
lib_user=lib_user,
)
user.save()
login(request, user)
messages.success(request, "Account Created successfully for " + username)
return redirect(signin)
else:
form = Signup()
return render(request, "accounts/register.html", {"form": form})
forms.py validation
def clean(self):
super(Signup, self).clean()
password = self.cleaned_data.get("password")
password2 = self.cleaned_data.get("password2")
username = self.cleaned_data.get("username")
email = self.cleaned_data.get("email")
staff_id = self.cleaned_data.get("staff_id")
matric_no = self.cleaned_data.get("matric_no")
library_id = self.cleaned_data.get("library_id")
if not staff_id:
self.cleaned_data["staff_id"] = None
So basically, i select if i user is a staff or student. If user is student, staff_id field is meant to return null to database. So how do i go about it.
Please check after changes null=True, blank=True you applied makemigrations and migrate command applied or not, if applied then try this code
------ Code - 1 ---------
def signup(request):
form = Signup()
if request.method == "POST":
form = Signup(request.POST)
if form.is_valid():
fm=form.save()
login(request, fm.user)
messages.success(request, "Account Created successfully for " + form.claned_data['username'])
return redirect(signin)
return render(request, "accounts/register.html", {"form": form})
--------- Code - 2 ------------
def signup(request):
form = Signup()
if request.method == "POST":
form = Signup(request.POST)
if form.is_valid():
username = form.cleaned_data["username"]
first_name = form.cleaned_data["first_name"]
last_name = form.cleaned_data["last_name"]
email = form.cleaned_data["email"]
password = form.cleaned_data["password"]
password2 = form.cleaned_data["password2"]
staff_id = form.cleaned_data["staff_id"]
matric_no = form.cleaned_data["matric_no"]
library_id = form.cleaned_data["library_id"]
designation = form.cleaned_data["designation"]
lib_user = form.cleaned_data["lib_user"]
user = User.objects.create_user(
username=username.lower(),
first_name=first_name.lower(),
last_name=last_name.lower(),
password=password,
email=email,
staff_id=staff_id,
matric_no=matric_no,
library_id=library_id,
designation=designation,
lib_user=lib_user,
)
user.save()
login(request, user)
messages.success(request, "Account Created successfully for " + username)
return redirect(signin)
return render(request, "accounts/register.html", {"form": form})
Related
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 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
I am editing profile using Django framework. The problem lies where the user login can see the profile of other user when they change the id in the web address. Could someone help me so that I can only view the user's profile who is login and if they change the id they will receive an error. Thanks
Edit User Profile
#login_required(login_url = 'signin')
#user_passes_test(check_role_super)
def sa_profile_edit(request, user_id=None):
user = get_object_or_404(User, pk=user_id)
user_profile = get_object_or_404(userMember, pk=user_id)
if request.method == 'POST':
form = UserFormAdmin(request.POST or None, instance=user)
form_profile = MemberForm(request.POST or None, instance=user_profile)
else:
form = UserFormAdmin(instance=user)
form_profile = MemberForm(instance=user_profile)
context = {
'form': form,
'user': user,
'form_profile': form_profile,
'user_profile': user_profile
}
return render(request, 'pages/sa_editProfile.html', context)
If role is super
def check_role_super(user):
if user.role == 3:
return True
else:
raise PermissionDenied
Model
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', blank=True, null=True)
created_at = models.DateTimeField(auto_now=True)
modified_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.user.username
You can get the current user from the request instead, replace user = get_object_or_404(User, pk=user_id) with:
user = request.user
if not user.is_authenticated:
raise Http404()
========= view.py ===========
# User Profile Update
def ProfileView(request):
if request.user.is_authenticated:
form =UserProfileChangeForm(instance=request.user)
context = {'form':form}
if request.method == 'POST':
form =UserProfileChangeForm(request.POST,instance=request.user)
if form.is_valid():
form.save()
messages.info(request,'Profile Successfully Updated')
return redirect('/profile/')
else:
form =UserProfileChangeForm(instance=request.user)
user_data = request.user
context = {'form':form,'user_data':user_data}
return rend
er(request,'profile.html',context)
======= form.py ========
from django.contrib.auth.forms import UserChangeForm
# User Profile
class UserProfileChangeForm(UserChangeForm):
password =None
class Meta:
model = User
fields = ['username','first_name','last_name','email']
widgets = {
'username':forms.TextInput(attrs={'class':'form-control','placeholder':'Enter Username'}),
'first_name':forms.TextInput(attrs={'class':'form-control','placeholder':'Enter First Name'}),
'last_name':forms.TextInput(attrs={'class':'form-control','placeholder':'Enter Last Name'}),
'email':forms.TextInput(attrs={'class':'form-control','placeholder':'Enter E-Mail'}),
}
you should implement class with UUID concept. UUID meant to protect url address.
but as short and not ideal solution
you can overwrite id in your code by request.user.id
lets say logged in user has id=3 and he tries to change it to id=4 and then view function will get called. but you can overwrite that id by as i said above and he ll end up seeing his profile anyways. but URL WILL display wrong id so this is not a good option.
I have a User model, an ApplicantProfile model, and a CompanyProfielModel. A user can be of two types, an applicant or a company.
models.py
class User(AbstractBaseUser):
email = models.EmailField(max_length=255, unique=True)
name = models.CharField(max_length=255)
date_joined = models.DateTimeField(auto_now_add=True)
is_applicant = models.BooleanField(default=False)
is_company = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']
objects = MyUserManager()
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
class ApplicantProfile(models.Model):
GENDER_MALE = 0
GENDER_FEMALE = 1
GENDER_CHOICES = [(GENDER_MALE, 'Male'), (GENDER_FEMALE, 'Female')]
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
image = models.ImageField(upload_to=image_directory_path, storage=image_storage, null=True, blank=True)
bio = models.TextField(max_length=500, null=True, blank=True)
address = models.TextField(max_length=200, null=True, blank=True)
birth_date = models.DateField(null=True, blank=True)
phone = PhoneNumberField(null=True, blank=True)
website = models.URLField(max_length=255, null=True, blank=True)
gender = models.IntegerField(choices=GENDER_CHOICES, null=True, blank=True)
interest = models.TextField(max_length=255, null=True, blank=True)
linkedin = models.CharField(max_length=255, null=True, blank=True)
github = models.CharField(max_length=255, null=True, blank=True)
twitter = models.CharField(max_length=255, null=True, blank=True)
facebook = models.CharField(max_length=255, null=True, blank=True)
def __str__(self):
return self.user.name
class CompanyProfile(models.Model):
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
image = models.ImageField(upload_to=image_directory_path, storage=image_storage, null=True, blank=True)
about = models.TextField(max_length=500, null=True, blank=True)
location = models.CharField(max_length=100, null=True, blank=True)
start_date = models.DateField(null=True, blank=True)
website = models.URLField(max_length=255, null=True, blank=True)
logo = models.ImageField(upload_to=image_directory_path, storage=image_storage, null=True, blank=True)
def __str__(self):
return self.user.name
I have two URLs to create two different types of users. I can create applicants automatically right after a user registers from the applicant registration url, but I can't create companies from the company registration url.
views.py
def applicant_register(request):
if request.method == 'POST':
form = ApplicantRegistrationForm(request.POST)
if form.is_valid():
form.save()
email = form.cleaned_data.get('email')
raw_password = form.cleaned_data.get('password1')
user = authenticate(email=email, password=raw_password)
ApplicantProfile.objects.create(user=user)
messages.success(request, "Account created successfully.")
return redirect('applicant-feed')
form = ApplicantRegistrationForm()
context = {
"form": form
}
return render(request, 'user/applicant/applicant-register.html', context)
def company_register(request):
if request.method == 'POST':
form = CompanyRegistrationForm(request.POST)
if form.is_valid():
form.save()
email = form.cleaned_data.get('email')
raw_password = form.cleaned_data.get('password1')
user = authenticate(email=email, password=raw_password)
CompanyProfile.objects.create(user=user) # This line gives the error
messages.success(request, "Account created successfully.")
return redirect('company-feed')
form = CompanyRegistrationForm()
context = {
"form": form
}
return render(request, 'user/company/company-register.html', context)
Any help is appreciated.
Getting this error in the browser
According to error, looks like CompanyProfile is not a model class but something else. Is there a chance that you redefine it in views.py? Probably you also define a view with this name?
you don't need to use the form because you can create an account directly to any model like this function
def company_register(request):
if request.method == 'POST':
user = request.POST['user']
image = request.FILES['image']
about = request.POST['about']
location = request.POST['location']
start_date = request.POST['start_date']
website = request.POST['website']
logo = request.FILES['logo']
profile = CompanyProfile.objects.create(user=user, image=image, about=about, location=location, start_date=start_date, website=website, logo=logo)
profile.save()
return Response('Done')
else:
return Response('POST method only accepted')
Weird issue with by registration form, not sure i am doing wrong.
I have StudentProfile Model, that I am trying to save data from StudentResistrationForm but the data is not being saved into database
ERROR: NameError at /register/ name 'StudentProfile' is not defined
Is the view logic correct? What am I missing? Ideas please
model
class Accounts(AbstractUser):
email = models.EmailField('email address', unique=True)
first_name = models.CharField('first name', max_length=30, blank=True)
last_name = models.CharField('last name', max_length=30, blank=True)
date_joined = models.DateTimeField('date joined', auto_now_add=True)
# asdd
bio = models.TextField(max_length=500, blank=True)
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
class StudentProfile(models.Model):
user = models.OneToOneField('Accounts', related_name='student_profile')
# additional fields for students
AMEB_Ratings = models.PositiveIntegerField(default=0)
is_student = models.BooleanField('student status', default=False)
form
class StudentResistrationForm(forms.ModelForm):
class Meta:
model = StudentProfile
fields = (
'AMEB_Ratings',
)
def save(self, commit=True):
user = super(StudentResistrationForm, self).save(commit=False)
# user.first_name = self.cleaned_data['first_name']
# user.last_name = self.cleaned_data['last_name']
user.AMEB_Ratings = self.cleaned_data['AMEB_Ratings']
if commit:
user.save()
return user
class UserForm(forms.ModelForm):
class Meta:
model = get_user_model()
fields = ('username', 'email', 'password')
view
def registerStudent(request):
# Once register page loads, either it will send to the server POST data (if the form is submitted), else if it don't send post data create a user form to register
if request.method == "POST":
user_form = UserForm(request.POST)
form = StudentResistrationForm(request.POST)
if form.is_valid() and user_form.is_valid():
User = get_user_model()
username = user_form.cleaned_data['username']
email = user_form.cleaned_data['email']
password = user_form.cleaned_data['password']
new_user = User.objects.create_user(username=username, email=email, password=password)
Student_profile = StudentProfile()
Student_profile.user = new_user
Student_profile.AMEB_Ratings = request.POST['AMEB_Ratings']
# Student_profile = StudentProfile.create_user(AMEB_Ratings=AMEB_Ratings)
new_user.save()
Student_profile.save()
# form.save()
# AMEB_Ratings = form.cleaned_data['AMEB_Ratings']
return redirect('/')
else:
# Create the django default user form and send it as a dictionary in args to the reg_form.html page.
user_form = UserForm()
form = StudentResistrationForm()
# args = {'form_student': form, 'user_form': user_form }
return render(request, 'accounts/reg_form_students.html', {'form_student': form, 'user_form': user_form })
Looks like you have a few typos you currently are setting your email variable to the email data then setting it to the password data. Correct this first.
email = user_form.cleaned_data['email']
password = user_form.cleaned_data['password']