When I complete the profile of a test user, it adds the name of the uploaded file to the DB, and I am able to access the user's profile image file name with {{ user.profile.profile_pic }}, however the image does not appear in my_project/media/images. Thanks for any advice.
Here are the relevant files, I can add more if needed:
settings.py (last two lines)
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
accounts/models.py
from django.db import models
from django.db import models
from django.contrib.auth.models import (
AbstractBaseUser, BaseUserManager
)
from django.db.models.signals import post_save
from django.dispatch import receiver
# Create your models here.
class UserManager(BaseUserManager):
def create_user(self, email, password=None, is_staff=False, is_superuser=False, is_active=True, is_confirmed=False):
if not email:
raise ValueError("Users must have an email address.")
if not password:
raise ValueError("Users mush have a password.")
user_obj = self.model(email = self.normalize_email(email))
user_obj.set_password(password) #also to change password
user_obj.staff = is_staff
user_obj.admin = is_superuser
user_obj.active = is_active
user_obj.confirmed = is_confirmed
user_obj.save(using=self._db)
return user_obj
def create_staffuser(self, email, password=None):
user = self.create_user(email, password=password, is_staff=True)
return user
def create_superuser(self, email, password=None):
user = self.create_user(email, password=password, is_staff=True, is_superuser=True)
return user
class User(AbstractBaseUser):
email = models.EmailField(max_length=255,unique=True)
USERNAME_FIELD = 'email'
active = models.BooleanField(default=False)
staff = models.BooleanField(default=False)
admin = models.BooleanField(default=False)
confirmed = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
#property
def is_staff(self):
return self.staff
#property
def is_admin(self):
return self.admin
#property
def is_active(self):
return self.active
#property
def is_confirmed(self):
#confirmed email address
return self.confirmed
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
#extend extra data, i.e. name, location, ect.
first_name = models.TextField(max_length=16)
profile_pic = models.ImageField(upload_to = 'images/')
#receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
accounts/views.py
def complete_setup(request):
user_id = request.user.id
if request.method == 'POST':
#handle form data
#and redirect to home or whatever they were looking at
user = User.objects.get(pk=user_id)
user.profile.first_name = request.POST["first_name"]
user.profile.profile_pic = request.POST["image"]
user.save()
return redirect('home')
else:
#serve form
#only serve if profile not complete
if request.user.is_authenticated:
print("user is logged in...")
try:
name = request.user.profile.name
print("user has completed profile")
return render(request, 'home')
except:
return render(request, 'accounts/complete-setup.html')
else:
print("user is not logged in")
return redirect('login')
instead of user.profile.profile_pic = request.POST["image"] use this
`user.profile.profile_pic = request.FILES["image"]`
also, hope yo have add enctype="multipart/form-data" in your form tag like this:
<form method="post" enctype="multipart/form-data">
add this in urls.py
urlpatterns = [
# urls
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Related
I'm currently working on a django project and I have a custom user model in my django app. Custom user authentication is working perfectly, but the issue I'm facing is whenever I'm logging into admin account in the django admin site, it logs out the previous user(let say, user2) and admin being logged in.
How Can I separate their login, so that admin site logins don't interfere with my website login?
Here is my code attached:
Custom User model and its manager:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class CustomerManager(BaseUserManager):
def create_user(self, email, username, name, password=None):
if not email:
raise ValueError('Users must have an email address to register')
if not username:
raise ValueError('Users must have an username address to register')
if not name:
raise ValueError('Users must enter their name to register')
user = self.model(
email = self.normalize_email(email),
username = username,
name=name,
)
user.set_password(password)
user.save(using = self._db)
return user
def create_superuser(self, email, username, name, password=None):
user = self.create_user(
email = self.normalize_email(email),
username = username,
name=name,
password=password,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class Customer(AbstractBaseUser):
# user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True)
email = models.EmailField(max_length=254, null=True, unique=True)
username = models.CharField(max_length=40, unique=True)
name = models.CharField(max_length=200)
phone = models.CharField(max_length=10, null=True)
address = models.CharField(max_length=500, null=True)
date_joined = models.DateTimeField(auto_now_add=True)
last_login = models.DateTimeField(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)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'name']
objects = CustomerManager()
def __str__(self):
return self.name
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
Login View:
def loginUser(request):
if request.user.is_authenticated:
return redirect('home')
else:
if request.method == 'POST':
email = request.POST.get('email')
password = request.POST.get('password')
user = authenticate(request, email=email, password=password)
if user is not None:
login(request, user)
return redirect('home')
else:
messages.info(request, 'Email or Password didn\'t match!')
context = {}
return render(request, 'accounts/login.html', context)
Logout View:
#login_required(login_url='login')
def logoutUser(request):
logout(request)
return redirect('login')
User Profile View:
#login_required(login_url='login')
def userProfile(request, email):
customer = Customer.objects.filter(email=email).first()
context = {'customer':customer}
return render(request, 'accounts/profile.html', context)
CreateUserForm and LoginForm:
class CreateUserForm(UserCreationForm):
class Meta:
model = Customer
fields = ['username', 'email', 'name', 'password1', 'password2']
# fields = '__all__'
class LoginForm(forms.ModelForm):
password = forms.CharField(label='password', widget=forms.PasswordInput)
class Meta:
model = Customer
fields = ['email', 'password']
def clean(self):
email = self.cleaned_data['email']
password = self.cleaned_data['password']
if not authenticate(email=email, password=password):
raise forms.ValidationError('Incorrect Login')
When User3 is logged in and admin is not logged in:
As soon as admin logged in:
User3 automatically logs out and admin logs in..
I have created a Custom User Model(I am new to this Curtom thing) And I got this error at login. NOT NULL constraint failed: users_usermodel.password. I don't understand what to do. Here is my models.py and views.py
I changes the login to mylogin because I thought the function might contrdict the django login funtion. but nothing changed. Please help me solve my problem
Models.py
# Custom User Model Code
from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)
class MyUserManager(BaseUserManager):
def create_user(self, email,first_name, last_name, password=None):
"""
Creates and saves a User with the given email, favorite color
and password.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
first_name=first_name,
last_name=last_name
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email,first_name, last_name, password):
"""
Creates and saves a superuser with the given email, date of
birth and password.
"""
user = self.create_user(
email,
password=password,
first_name=first_name,
last_name=last_name,
)
user.is_admin = True
user.is_superuser = True
user.save(using=self._db)
return user
class UserModel(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
first_name = models.CharField(max_length=20, default='')
last_name = models.CharField(max_length=20, default='')
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
objects = MyUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name','last_name']
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
#property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
views.py
from django.shortcuts import render
from django.shortcuts import redirect
from django.contrib.auth import logout
from .models import UserModel
# Create your views here.
def profile(request):
return render(request, '/users/profile.html')
def register(request):
if request.method == 'POST':
first_name = request.POST.get('firstname')
last_name = request.POST.get('lastname')
email = request.POST.get('email')
password1 = request.POST.get('password1')
password2 = request.POST.get('password2')
if password1 == password2:
user = UserModel(first_name=first_name, last_name=last_name, email=email, password=password1)
user.save()
return render(request, 'users/login.html')
else:
message = 'Invalid Credentials'
return redirect('users/register.html', {'message':message})
return render(request,'users/register.html')
def login(request):
if request.method == 'POST':
email = request.POST.get('email')
password = request.POST.get('password')
print(password)
try:
user = UserModel.objects.get(email=email)
if password == user.password:
return redirect(request, 'themes/index.html')
else:
message = 'Invali Credentials'
return render(request,'users/login.html', {'message':message})
except:
message = 'Invalid Credentials'
return render(request,'users/login.html', {'message':message})
return render(request,'users/login.html')
def userlogout(request):
logout(request)
return redirect('home')
In your manager,you have password set as None,that's y it's throwing this error,just set your function like the following _create_user(self,email,first_name,last_name,password):
this should fix your problem,and also don't forget to setup AUTH_USER_MODEL in settings.
I am trying to login using email instead of username in django, but it is not working. I am not getting any error also.
I also looked up solution for solutions in stackoverflow and other blogs/post also but not getting the output.
Can you please review my code where I am wrong/ modification needed.
Any suggestions or changes are welcome.
Here is my code:
models.py
from django.db import models
from django.contrib.auth.models import (BaseUserManager,AbstractBaseUser)
# Create your models here.
class UserManager(BaseUserManager):
def create_user(self, email,password=None):
"""
Creates and saves a User with the given email, date of
birth and password.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email),
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, date_of_birth, password):
"""
Creates and saves a superuser with the given email, date of
birth and password.
"""
user = self.create_user(
email,
password=password,
)
user.is_admin = True
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser):
email = models.EmailField(verbose_name='email address',
max_length=255,
unique=True,
)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
#property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
views.py
from django.shortcuts import render
from django.contrib.auth.models import User
from django.contrib.auth import get_user_model,authenticate
from .forms import RegisterForm,LoginForm
# Create your views here.
def home(request):
return render(request,'home.html',{})
def register_view(request):
form = RegisterForm(request.POST or None)
context = {"form":form}
if form.is_valid():
email = form.cleaned_data['email']
password = form.cleaned_data['password']
new_user = User.objects.create_user(email,password)
return render(request,'register.html',context)
def login_view(request):
form = LoginForm(request.POST or None)
context = {"form" : form}
if form.is_valid():
username = form.cleaned_data.get("username")
password = form.cleaned_data.get("password")
user = authenticate(request,username = username,password=password)
if user is not None:
login(request, user)
print("Looged In")
return redirect('home')
else:
print("Username or Password is Wrong")
return render(request,'login.html',context)
backends.py
from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
class EmailBackend(ModelBackend):
def authenticate(self, username=None, password=None, **kwargs):
UserModel = get_user_model()
try:
user = UserModel.objects.get(email=username)
except UserModel.DoesNotExist:
return None
else:
if user.check_password(password):
return user
return None
settings.py
AUTHENTICATION_BACKENDS = ['profile_manager.backends.EmailBackend']
AUTH_USER_MODEL = 'profile_manager.MyUser'
forms.py
from django import forms
from django.contrib.auth import get_user_model
from django.contrib.auth.models import User
from .models import MyUser
User = get_user_model()
class RegisterForm(forms.Form):
email =forms.EmailField(widget = forms.TextInput(
attrs = {"class":"form-control",
"placeholder":"Email"
}),label='')
password = forms.CharField(widget =forms.PasswordInput(attrs = {"class":"form-control",
"placeholder":"Password"
}),label='')
password2 = forms.CharField(label ='' , widget = forms.PasswordInput(attrs = {"class":"form-control",
"placeholder":"Confirm Password"
}))
def clean_email(self):
email = self.cleaned_data.get('email')
qs = User.objects.filter(email =email)
if qs.exists():
raise forms.ValidationError("Email is already taken")
return email
def clean(self):
data =self.cleaned_data
password = self.cleaned_data.get('password')
password2 = self.cleaned_data.get('password2')
if password2!= password:
raise forms.ValidationError("Password must match")
return data
class LoginForm(forms.Form):
email = forms.EmailField(widget = forms.TextInput(
attrs = {"class":"form-control",
"placeholder":"Username"
}),label='')
password = forms.CharField(widget =forms.PasswordInput(attrs = {"class":"form-control",
"placeholder":"Password"
}),label='')
This line in your login_view can't be right:
username = form.cleaned_data.get("username")
Your form doesn't have a username field, it only has an email field.
When I try to login users registered through my AbstractBaseUser model I get the error:
'AnonymousUser' object has no attribute '_meta'
Which highlights the code:
login(request, user)
However, if the user is an admin there is no problem, leaving me to believe that the problem isn't with the 'login_view', but a problem with how the user is tagged (so to speak) when they are registered with AbstractBaseUser.
Any help would be much appreciated!
Here is my code:
Models.py
from django.db import models
from django.contrib.auth.models import (
AbstractBaseUser, BaseUserManager, PermissionsMixin
)
class UserManager(BaseUserManager):
def create_user(self, first_name, last_name, email, password=None, is_active=True, is_staff=False, is_admin=False):
if not first_name:
raise ValueError("Users must enter their first name")
if not last_name:
raise ValueError("Users must enter their last name")
if not email:
raise ValueError("Users must enter an email")
if not password:
raise ValueError("Users must enter a password")
user_obj = self.model(
first_name = first_name,
last_name = last_name,
email = self.normalize_email(email),
)
user_obj.set_password(password) #set and change password?
user_obj.admin = is_admin
user_obj.staff = is_staff
user_obj.active = is_active
user_obj.save(using=self._db)
return user_obj
def create_superuser(self, first_name, last_name, email, password=None):
user = self.create_user(
first_name,
last_name,
email,
password=password,
is_staff=True,
is_admin=True
)
return user
class User(AbstractBaseUser, PermissionsMixin):
first_name = models.CharField(max_length=255, blank=True, null=True)
last_name = models.CharField(max_length=255, blank=True, null=True)
email = models.EmailField(max_length=255, unique=True)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
active = models.BooleanField(default=True) #can login
staff = models.BooleanField(default=False) #staff not superuser
admin = models.BooleanField(default=False) #superuser
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name']
objects = UserManager()
def __str__(self):
return self.email
def get_first_name(self):
return self.email
def get_last_name(self):
return self.email
def get_short_name(self):
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
#property
def is_staff(self):
return self.staff
#property
def is_admin(self):
return self.admin
#property
def is_active(self):
return self.active
Forms.py
from django import forms
from django.contrib.auth import (
authenticate,
get_user_model,
login,
logout,
)
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.contrib.auth.models import User, Group
User = get_user_model()
class UserAdminCreationForm(forms.ModelForm):
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')
def save(self, commit=True):
user = super(UserAdminCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class UserAdminChangeForm(forms.ModelForm):
password = ReadOnlyPasswordHashField()
class Meta:
model = User
fields = ('email', 'first_name', 'last_name', 'password', 'admin')
def clean_password(self):
return self.initial["password"]
class LoginForm(forms.Form):
username = forms.CharField(label='Email')
password = forms.CharField(widget=forms.PasswordInput)
Views.py
from django.shortcuts import render
from django.contrib.auth.models import User, Group
from django.contrib.auth import (
authenticate,
get_user_model,
login,
logout,
)
from django.shortcuts import redirect
from .forms import UserAdminCreationForm, LoginForm
def register_view(request):
form = UserAdminCreationForm(request.POST or None)
if form.is_valid():
user = form.save(commit=False)
password = form.cleaned_data.get('password')
user.set_password(password)
user.save()
user.groups.add(Group.objects.get(name='customers'))
login(request, user)
context = {
"form": form,
}
return render (request, "register.html", context)
def login_view(request):
form = LoginForm(request.POST or None)
if form.is_valid():
username = form.cleaned_data.get("username")
password = form.cleaned_data.get("password")
user = authenticate(username=username, password=password)
login(request, user)
context = {
"form": form,
}
return render (request, "login.html", context)
Try using the methods that the BaseClass provides. That will prevent you from making unexpected errors.
You can use super() for that purpose.
Hi how are I having a problem with my django user authentication since I am using AbstractBaseUser
Model
from Apps.grupo.models import Grupo
from Apps.empresa_area.models import Empresa_area
from Apps.archivos.models import Archivos
from django.db import models
from django.contrib.auth.models import (
AbstractBaseUser,
BaseUserManager,
Group,
)
class UserManager(BaseUserManager):
def create_user(self, email, password=None, is_staff=False, is_admin=False):
if not email:
raise ValueError("Usuuario tiene email")
if not password:
raise ValueError("usuario debe tener contraseƱa")
user_obj = self.model(
email =self.normalize_email(email)
)
user_obj.set_password(password)
user_obj.staff = is_staff
user_obj.admin = is_admin
user_obj.active = is_active
user_obj.save(using=self._db)
return user_obj
def create_staffuser(self, email, password=None):
user = self.create_user(
email,
password=password,
is_staff=True
)
return user
def create_superuser(self, email, password=None):
user = self.create_user(
email,
password=password,
is_staff=True,
is_admin=True,
)
return user
class User(AbstractBaseUser):
email = models.EmailField(max_length=200, unique=True)
active = models.BooleanField(default=True)
staff = models.BooleanField(default=False)
admin = models.BooleanField(default=False)
celular = models.CharField(max_length=20)
saludo = models.CharField(max_length=10)
grupo = models.ForeignKey(Grupo, null=True, blank=True, on_delete=models.CASCADE)
archivo = models.ForeignKey(Archivos, null=True, blank=True, on_delete=models.CASCADE)
fec_creacion = models.DateTimeField(auto_now=False, auto_now_add=False)
empresa_area_id = models.ForeignKey(Empresa_area, null=True, blank=True, on_delete=models.CASCADE)
cargo = models.ManyToManyField(Group)
USERNAME_FIELD = 'email'
REQUIRED_FILES = []
objects = UserManager()
class Meta:
verbose_name = ('user')
verbose_name_plural = ('users')
def __str__(self):
return self.email
def get_full_name(self):
return self.email
def get_short_name(self):
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
#property
def is_staff(self):
return self.staff
#property
def is_admin(self):
return self.admin
#property
def is_active(self):
return self.active
In this model is giving the permissions to validate me by email also I have in this view where user authentication is generated
view
from django.contrib.auth import (
get_user_model,
authenticate,
login,
logout,
)
from django.views.generic import CreateView, FormView
from django.utils.http import is_safe_url
from django.shortcuts import render, redirect
from .forms import Login
User = get_user_model()
class LoginView(FormView):
form_class = Login
succes_url = '/'
template_name = 'Login.html'
def form_valid(self, form):
request = self.request
next_post = request.POST.get('next')
next_ = request.GET.get('next')
password = form.cleaned_data.get("password")
email = form.cleaned_data.get("email")
user = authenticate(request, username=email, password=password)
if user is not None:
login(request, user)
try:
del request.session['email']
except:
pass
return super(LoginView, self).form_invalid()
It is validating but it is generating the following error
form_invalid() missing 1 required positional argument: 'form'
You need to pass the form parameter to the super class call to form_invalid i.e
return super(LoginView, self).form_invalid(form)