Authentication failure: Login page returns DoesNotEXist for users already in the database - django-models

I am trying to grasp Python Django. I'm trying to make a bank system web application. I can register users. These users then are automatically logged in. However, after logout I cannot login the same user again. The page tells me the user does not exist
I have tried to play around with my backends.py in the terminal. when i run
$ user=User.objects.get(pk=1)
$ user
it returns the user with the id in the database. However it doesnt work with the login page. Kindly help, I have been stuck for a week.
models.py:
class UserManager(BaseUserManager):
def create_user(self, account_no, password=None, **extra_fields):
"""
Create and save a user with the given account_no and password.
"""
user = self.model(account_no=account_no, **extra_fields)
user.set_password(password)
user.save(using=self._db)
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return user
def create_superuser(self, email, password, **extra_fields):
"""
Creates and saves a superuser with the given email and password.
"""
user = self.create_user(email, password=password, **extra_fields)
user.is_admin = True
user.save(using=self._db)
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('account_no', False)
extra_fields.setdefault('is_superuser', True)
return user
class User(AbstractUser):
username = models.CharField(
('username'), max_length=30, unique=True, null=True, blank=True)
email = models.EmailField(unique=True, blank=True, null=True)
contact_no = models.IntegerField(unique=False, null=True,blank=True)
account_no = models.PositiveIntegerField(
unique=True,
validators=[
MinValueValidator(1000000000),
MaxValueValidator(9999999999)
])
balance = models.DecimalField(
default=0,
max_digits=12,
decimal_places=2
)
GENDER_CHOICE = (
("M", "Male"),
("F", "Female"),
)
gender = models.CharField(max_length=1, choices=GENDER_CHOICE)
birth_date = models.DateField(null=True, blank=True)
city = models.CharField(max_length=256, blank=True, null=True)
postal_code = models.PositiveSmallIntegerField(blank=True, null=True)
country = models.CharField(max_length=256, blank=True, null=True)
picture = models.ImageField(
null=True,
blank=True,
upload_to='account_pictures/',
)
objects = UserManager()
USERNAME_FIELD = 'account_no'
REQUIRED_FIELDS = ['first_name', 'last_name', ]
def __str__(self):
return str(self.full_name)
views.py:
def login_view(request):
if request.user.is_authenticated:
return redirect('home')
else:
form = UserLoginForm(request.POST)
if form.is_valid():
account_no = form.cleaned_data.get('account_no')
password = form.cleaned_data.get('password')
user = authenticate(account_no=account_no, password=password)
login(request, user, backend='accounts.backends.ModelBackend')
messages.success(request, 'Welcome, {}!'.format(user.full_name))
return redirect("home")
context = {"form": form,
"title": "Load Account Details",
}
return render(request, "accounts/login.html", context)
backends.py:
from django.contrib.auth import get_user_model
User = get_user_model()
class ModelBackend(object):
def authenticate(self, request, account_no=None, password=None):
try:
user = User.objects.get(account_no=account_no)
if user and user.check_password(password):
return user
except User.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
forms.py:
class UserLoginForm(forms.Form):
account_no = forms.IntegerField(label="Account Number")
password = forms.CharField(widget=forms.PasswordInput)
def clean(self, *args, **kwargs):
account_no = self.cleaned_data.get("account_no")
password = self.cleaned_data.get("password")
if account_no and password:
user = authenticate(account_no=account_no, password=password)
if not user:
raise forms.ValidationError("Account Does Not Exist.")
if not user.check_password(password):
raise forms.ValidationError("Password Does not Match.")
if not user.is_active:
raise forms.ValidationError("Account is not Active.")
return super(UserLoginForm, self).clean(*args, **kwargs)
The user that has been registered should be able to login. The program keeps denying registered users from logging in.

Related

Updating a profile image in django

so I have this issue when trying to update a profile photo in django.
The Profile photo actually updates if I upload an image. But there are cases where a user may want to update other details on the profile update page without having to update the profile photo.
Trying to implement that gave me a multivalue error.
I've been on it for some time now, Please, who knows how I can handle that.
Here's my code on views.py file
def profile_update(request, user_id):
if request.method == 'POST':
user_obj = User.objects.get(id=user_id)
user_profile_obj = UserProfile.objects.get(user=user_id)
user_img = request.FILES['user_img']
username = request.POST["username"]
email = request.POST["email"]
phone = request.POST["phone"]
address = request.POST["address"]
fs_handle = FileSystemStorage()
img_name = 'uploads/profile_pictures/user_{0}'.format(user_id)
if fs_handle.exists(img_name):
fs_handle.delete(img_name)
fs_handle.save(img_name, user_img)
user_profile_obj.profile_pic = img_name
user_profile_obj.phone = phone
user_profile_obj.address = address
user_profile_obj.save()
user_obj.username = username
user_obj.email = email
user_obj.save()
user_obj.refresh_from_db()
Here's my models.py file
`
class UserProfile(models.Model):
user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
address = models.CharField(max_length=65, null=True, blank=True)
phone = models.CharField(max_length=65, null=True, blank=True)
profile_pic = models.FileField(null=True, blank=True, upload_to="uploads/profile_pictures", validators = [FileExtensionValidator(allowed_extensions=['jpg','jpeg','png'])])
def __str__(self):
return str(self.user)
`

Custom authentication token for custom Users in Django Rest Framework

I am very new to Django Framework, I am trying to use Custom user model and Custom authentication for my project.
please find below code for Create Custom Model and Custom authentication.
Custom User Model
class User(AbstractUser):
userID = models.AutoField(primary_key=True)
Employee = models.ForeignKey(EMP, on_delete=models.CASCADE, null=True)
User Serializer
class ValidateUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('Employee', 'first_name', 'last_name',
'email', 'username', 'password')
def create(self, validated_data):
User = get_user_model()
Employee = validated_data.pop('Employee')
first_name = validated_data.pop('first_name')
last_name = validated_data.pop('last_name')
email = validated_data.pop('email')
username = validated_data.pop('username')
password = validated_data.pop('password')
return User.objects.create(Employee =Employee ,
first_name=first_name, last_name=last_name, email=email, username=username, password=None, **validated_data)
Views.py
#api_view(['GET', 'POST'])
def users(request):
if request.method == 'GET':
users = Users.objects.all()
print(users.query)
data = UserTempSerializer(users, many=True).data
return JsonResponse(data, safe=False)
elif request.method == 'POST':
users_data = JSONParser().parse(request)
user_serilizer = ValidateUserSerializer(data=users_data)
if user_serilizer.is_valid():
user_serilizer.save()
return JsonResponse(user_serilizer.data, status=status.HTTP_201_CREATED)
print(user_serilizer.errors)
return JsonResponse(user_serilizer.errors, status=status.HTTP_400_BAD_REQUEST)
Custom authentication Code Here:
class CustomAuthToken(ObtainAuthToken):
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data,
context={'request': request})
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
return Response({
'token': token.key,
'user_id': user.pk,
'first_name': user.first_name,
'email': user.email
})
I am not able to create the users and not able to authincate users.
I am getting below error try to authenticate the user:
Bad Request: /api/auth/
[06/Jul/2021 10:59:38] "POST /api/auth/ HTTP/1.1" 400 68
Could you please anybody help, Do I made wrong or flow are wrong.
Thanks in advance !!!!

Identify the custom user model in REST_FRAMEWORK settings Django

I'm new in Django rest_framework. I'm using a custom user model and djoser as my authentication system. I want to use my custom user model in the djoser register view and I don't know how to identify that in the rest_framework settings?
settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSIONS_CLASSES':(
'rest_framework.permissions.IsAuthenticated',
),
}
models.py
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, phone, password=None):
if not email:
raise ValueError("Users must have an email address")
if not username:
raise ValueError("Users must have an username")
if not phone:
raise ValueError("Users must have a phone number")
user = self.model(
email=self.normalize_email(email),
username=username,
phone=phone
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self,email, username, phone, password):
user = self.create_user(
email=self.normalize_email(email),
username=username,
phone=phone,
password=password
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name="email",max_length=60, unique=True)
username = models.CharField(max_length=60,unique=True)
phone = models.CharField(max_length=60,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=60,null=True)
last_name = models.CharField(max_length=60,null=True)
wilaya = models.CharField(max_length=60,null=True)
city = models.CharField(max_length=60,null=True)
address = models.CharField(max_length=200,null=True)
store_coordinates = models.CharField(max_length=60,null=True)
documents1 = models.CharField(max_length=60,null=True)
documents2 = models.CharField(max_length=60,null=True)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email','phone']
objects = MyAccountManager()
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
What should I add to use my custom user model in djoser register view?
You're doing almost everything right, but you need to tell Django in the settings what user model it should use.
In models.py use something like this
from django.contrib.auth.models import AbstractUser
from .managers import UserManager
class User(AbstractUser):
# Add whatever fields you want
# Use your custom manager
objects = UserManager()
In settings.py
# Tell Django what user model should be used
AUTH_USER_MODEL = 'auth.User' # app_label.model
make sure you use python manage.py makemigrations && python manage.py migrate to create your custom user model.
Enjoy!

'Account' object has no attribute 'products' AND (fields.E301) Field defines a relation with the model 'auth.User', which has been swapped out.'

I am following Django rest_framework tutorial to build my app but and I'm using a custom user model (Account) which inherits AbstractBaseUser.
I have another model - Product - and each product is owned by an Account.
My models.py is:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.conf import settings
class Product(models.Model):
owner = models.ForeignKey(Account, related_name='account', on_delete=models.CASCADE, default=1)
name = models.CharField(max_length=71)
product = models.CharField(max_length=20, blank=True)
price = models.IntegerField(null=True, blank=True)
quantity = models.IntegerField(default=0)
image = models.ImageField(upload_to='images', blank=True)
display = models.BooleanField(default=False)
created = models.DateTimeField('date added', auto_now=True)
modified = models.DateTimeField('date modified', auto_now_add=True)
def __str__(self):
return self.name
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, password=None):
if not email:
raise ValueError("Please enter a valid email address")
if not username:
raise ValueError("Please enter a username")
user = self.model(
email = self.normalize_email(email),
username = username,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, password):
user = self.create_user(
email = self.normalize_email(email),
password = password,
username = username,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class 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_add=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)
is_merchant = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = MyAccountManager()
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
My settings.py includes:
AUTH_USER_MODEL = 'accounts.Account'
My serializers.py is:
from rest_framework import serializers
from inventory.models import Product
from accounts.models import Account
class AccountSerializer(serializers.ModelSerializer):
products = serializers.PrimaryKeyRelatedField(many=True, queryset=Product.objects.all())
password2 = serializers.CharField(style={'input_type': 'password'}, write_only=True)
class Meta:
model = Account
fields = ['products', 'email', 'username', 'password', 'password2']
extra_kwargs = {
'password': {'write_only': True}
}
def save(self):
account = Account(
email = self.validated_data['email'],
username = self.validated_data['username'],
)
password = self.validated_data['password']
password2 = self.validated_data['password2']
if password != password2:
raise serializers.ValidationError({'password': 'Passwordss must match.'})
account.set_password(password)
account.save()
return account
class ProductSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.email')
class Meta:
model = Product
fields = [
'id', 'owner', 'name', 'product', 'price', 'quantity', 'image', 'display'
]
My views.py is:
from accounts.api.serializers import AccountSerializer
from inventory.api.serializers import ProductSerializer
from inventory.models import Product
from accounts.models import Account
from rest_framework import permissions
from rest_framework import generics
class AccountList(generics.ListAPIView):
queryset = Account.objects.all()
serializer_class = AccountSerializer
class AccountDetail(generics.RetrieveAPIView):
queryset = Account.objects.all()
serializer_class = AccountSerializer
class ProductList(generics.ListCreateAPIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
queryset = Product.objects.all()
serializer_class = ProductSerializer
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
class ProductDetail(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
queryset = Product.objects.all()
serializer_class = ProductSerializer
I am able to view my ProductList and ProductDetail however, I get the following error when I try to view AccountList and AccountDetail:
**Exception Type:** AttributeError
**Exception Value:** 'Account' object has no attribute 'products'
Just change your serailzier like this
class AccountSerializer(serializers.ModelSerializer):
products = serializers.SerializerMethodField()
password2 = serializers.CharField(style={'input_type': 'password'}, write_only=True)
def get_products(self, instance):
return Product.objects.all().values_list('id', flat=True)
class Meta:
model = Account
fields = ['products', 'email', 'username', 'password', 'password2']
extra_kwargs = {
'password': {'write_only': True}
}
def save(self):
account = Account(
email = self.validated_data['email'],
username = self.validated_data['username'],
)
password = self.validated_data['password']
password2 = self.validated_data['password2']
if password != password2:
raise serializers.ValidationError({'password': 'Passwordss must match.'})
account.set_password(password)
account.save()
return account
PrimaryKeyRelatedField may be used to represent the target of the relationship using its primary key. The queryset used for model instance lookups when validating the field input. Your field is read_only field. Your should use SerializerMethodField for this.

How to add custom user field (phone_number) in django default user table?

I need to add a custom field called phone_number to the default django user table
Everything work fine but the phone_number field and value does not save in Table Django User.
Here is my custom form code
class SignUpForm(UserCreationForm):
username = forms.EmailField(label="Email Address", max_length=254, help_text='Required a valid email address.')
phone_number = forms.CharField(max_length=30, help_text='Required.')
class Meta:
model = User
fields = ('first_name', 'last_name', 'username', 'phone_number', 'password1', 'password2')
Here is my view code for user registration
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False
user.save()
current_site = get_current_site(request)
mail_subject = 'Activate Your Account.'
message = render_to_string('app/account_activation_email.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)).decode(),
'token': account_activation_token.make_token(user),
})
to_email = form.cleaned_data.get('username')
email = EmailMessage(
mail_subject, message, to=[to_email]
)
email.send()
return render(request, 'app/account_confirm_message.html')
else:
form = SignUpForm()
return render(request, 'app/signup.html', {'form': form})
My Model is here
class Profile(models.Model):
STUDENT = 1
TEACHER = 2
ROLE_CHOICES = (
(STUDENT, 'Student'),
(TEACHER, 'Teacher'),
)
user = models.OneToOneField(User, on_delete=models.CASCADE)
email_confirmed = models.BooleanField(default=False)
role = models.PositiveSmallIntegerField(choices=ROLE_CHOICES, null=True, blank=True)
# this method called for admin panel
class Meta:
verbose_name = 'profile'
verbose_name_plural = 'profiles'
def __str__(self):
return self.user.username
#receiver(post_save, sender=User)
def update_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
instance.profile.save()

Resources