i am not an expert in custom user models in Django, so i started to use only AbstractUser class to be able to extend Auth functions, but i got this url pattern after login that shouldn’t be existed at all
http://localhost:8000/accounts/profile/
**
while my url in account app is
path(<int:id>, details, name = profile)
so when i logged in i got 404 doesn’t exist accounts/profile
** while it should be accounts/1
according to my view function return redirect('accounts:profile')
Also i have a custom user model and when i create new user i got
AnonymousUser’ object has no attribute ‘_meta’
i have both signup and login functions as follows
def sign_up(request):
# redirect a user to the home page if he is already logged in
if request.user.is_authenticated:
user = get_user_model().objects.get(id=request.user.id)
profile = Profile.objects.get(user=user)
return render(request, 'account/profile.html', {'form': profile})
if request.method == 'POST':
# replace UserCreationForm with SignUpForm for user acc. creation
form = CustomUserCreationForm(request.POST) # instead of form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password1')
#user.set_password(password)
#user.save()
user = authenticate(request, username=username, password=password)
# Profile.objects.create(user=new_user) #that line already been created by the signal
login(request, user)
# display a nice message when a new user is registered
messages.success(request, _('Your profile was successfully created!')) # messages.info(request,"Successfully Register ...")
return redirect('accounts:profile')
else:
return render(request, 'registration/signup.html', {'form': form})
else:
form = CustomUserCreationForm() # replace UserCreationForm with SignUpForm == form = UserCreationForm()
return render(request, 'registration/signup.html', {'form': form})
def log_in(request):
if request.user.is_authenticated:
return redirect('accounts:profile') # return render(request, 'homepage.html')
if request.method == "POST":
form = LoginForm(data=request.POST)
if form.is_valid():
username = form.cleaned_data('username')
password = form.cleaned_data('paswword')
try:
user = User.objects.get(username=username)
except:
messages.error(request, 'Username does not exist!')
# We check if the data is correct
user = authenticate(request, username=username, password=password)
if user: # If the returned object is not None
login(request, user) # we connect the user
return redirect('accounts:profile') # return redirect('/')
else: # otherwise an error will be displayed
messages.error(request, 'Invalid email or password')
return render(request, 'registration/login.html', {'form': form})
else:
form = LoginForm()
return render(request, 'registration/login.html', {'form': form})
my custome user model is
class User(AbstractUser):
# if you need any other information regarding any type of these following kinds of users make a model for them
USER_TYPE_CHOICES = (
(1, 'admin'),
(2, 'supervisor'),
(3, 'instructor'),
(4, 'student'),
(5, 'customer'),
(6, 'employee'),
(7, 'advertiser'),
)
# sys_id = models.AutoField(primary_key=True, blank=True)
email = models.EmailField(verbose_name='email address', max_length=255, unique=True,)
is_active = models.BooleanField(default=True)
is_superuser = models.BooleanField(default=False) #is_admin = models.BooleanField(default=False)
objects = newUserManager()
USERNAME_FIELD = 'email' # string describing the name of the field on
# the User model that is used as the unique identifier
REQUIRED_FIELDS = ["username"] # list of the field names that will be prompted
# for when creating a user via thecreatesuperuser management command
# roles = models.ManyToManyField(Role)
# the next line has null=True to not having validation error when creating Superuser at the begining
# django.db.utils.IntegrityError: null value in column "user_type" of relation "user_user" violates not-null constraint
user_type = models.PositiveSmallIntegerField(choices=USER_TYPE_CHOICES, null=True, blank=True)
class Meta:
#app_label = "user" # or 'auth'
#db_table = "users"
#verbose_name = _('User')
#verbose_name_plural = _('Users')
permissions = [
("change_post_status", "Can change the status of posts"),
("close_discussions", "Can remove a post by setting its status as closed"),
('can_publish', 'Can Publish Posts'),
]
def __str__(self):
return self.email
# this methods are require to login super user from admin panel
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, eturn True always or return self.is_superuser
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 or return self.
return True
def get_full_name(self):
'''
Returns the first_name plus the last_name, with a space in between.
'''
full_name = '%s %s' % (self.first_name, self.last_name)
return full_name.strip()
def get_short_name(self):
'''
Returns the short name for the user.
'''
return self.first_name
def email_user(self, subject, message, from_email=None, **kwargs):
'''
Sends an email to this User.
'''
send_mail(subject, message, from_email, [self.email], **kwargs)
@property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_superuser
and my custom user creation form is
class CustomUserCreationForm(UserCreationForm): # as we have a odel but has only username as emails
"""A form for creating new users. Includes all the required
fields, plus a repeated password."""
password1 = forms.CharField(label='Password', widget=forms.PasswordInput) # You can remove those two fields as they are already been existed
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta(UserCreationForm.Meta): # UserCreationForm has already all default fields, so you just need to add the additional fields to it
model = User
#fields = UserCreationForm.Meta.fields + ('user_type',) # birth date's been removed and added to profile model
fields = ('username', 'email', ) # if you have any other special field add it here
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise ValidationError("Passwords don't match")
return password2
def clean_username(self):
# Since User.username is unique, this check is redundant,
# but it sets a nicer error message than the ORM.
username = self.cleaned_data["username"]
try:
#User.objects.get(username=username)
User._default_manager.get(username=username)
except User.DoesNotExist:
return username
raise forms.ValidationError(self.error_messages['duplicate_username'])
def save(self, commit=True):
# Save the provided password in hashed format
user = super().save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
what i am doing wrong here pleeeeeease help me i am disparate of this