简体   繁体   中英

Type object has no attribute authentication

I am using custom table for login and registration of user, But I am getting error in login for not matching data with same table of user.

While using user = userInfo.authenticate(username=username,password=password) I am getting error for

type object 'userInfo' has no attribute 'authenticate'.

Also while registering i am encripting password by, "password=make_password(password1)"

Here my code is:

I have changed user model in settings file.

settings.py

AUTH_USER_MODEL = 'assets.userInfo'

models.py

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import AbstractBaseUser,BaseUserManager ,UserManager


class userInfo(AbstractBaseUser): 
    first_name = models.CharField(max_length=200)
    last_name = models.CharField(max_length=200)
    username = models.CharField(max_length=200)
    email = models.EmailField(max_length=200,verbose_name="email" , unique=True)
    password = models.CharField(max_length=200)
    abn = models.CharField(max_length=200)
    password = models.CharField(max_length=200) 
    isActive = models.BooleanField(default=True) 
    created_date = models.DateTimeField(default=timezone.now)

    REQUIRED_FIELDS =['username']
    USERNAME_FIELD = 'email'
    objects = UserManager()
    class Meta:
       db_table="userInfo"

views.py

from django.shortcuts import render, redirect
from django.contrib.auth import authenticate
from django.contrib.auth.models import User , auth 
from django.contrib import messages
from .models import userInfo , sector ,companyInfo ,capability , saleStages ,companySaleStages
from django.contrib.auth.hashers import make_password  
from .forms import CompanyDataForm
# Create your views here.  

def register(request):

    if request.method == 'POST':
        first_name = request.POST['first_name']
        last_name = request.POST['last_name']
        username = request.POST['username']
        password1 = request.POST['password1']
        password2 = request.POST['password2']
        abn = request.POST['abn']
        email = request.POST['email']

        if password1==password2:
            if userInfo.objects.filter(username=username).exists():
                messages.info(request,'Username Taken')
                return redirect('register')
            elif userInfo.objects.filter(email=email).exists():
                messages.info(request,'Email Taken')
                return redirect('register')
            elif userInfo.objects.filter(abn=abn).exists():
                messages.info(request,'ABN Number Taken')
                return redirect('register')
            else:   
                user = userInfo.objects.create(username=username, password=make_password(password1), email=email,first_name=first_name,last_name=last_name,abn=abn)
                user.save()
                # user.id();  Foo.objects.latest('id')
                print('user created')
              #  return redirect('register')
                return redirect('sector')

        else:
            messages.info(request,'password not matching..')    
            return redirect('register')
        return redirect('/')
        
    else:
        return render(request,'assets/register.html')

def login(request):
    if request.method== 'POST':
        username = request.POST['username']
        password = request.POST['password']

        user = userInfo.authenticate(username=username,password=password)

        if user is not None:
            auth.login(request, user)
            return redirect("/")
        else:
            messages.info(request,'invalid credentials')
            return redirect('login')

    else:
        return render(request,'assets/login.html')  

For registration its adding data in database but not authenticating data for login.

When you used the AbstractBaseUser class to customize the default user model it will create the only mention field like you had mentioned first_name, last_name, username, email, password , van, isActive, created_date

Here you had made mistake is Django has its own way to create password we have to follow only that specific step

password manage by Django using PermissionMixin and we are used AbstractBaseUser , AbstractUser or User any user Extending feature we must follow password management and that why we are able to create user, set_password, authenticate login, logout, etc predefined methods otherwise not

So here you have to follow as well if you used AbstractBaseUser , AbstractUser or User any user Extending feature also inherit PermissionMixin that handles all authentication method

have look updated model is and import following classes or methods,

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import AbstractBaseUser,BaseUserManager ,UserManager, PermissionsMixin
from django.conf import settings

# Create UserProfileManager using BaseUserManager because if we added a new field in the user model we have to assign create time as well

# manager
class UserProfileManager(BaseUserManager):
    """ Model Manager for Profiles """

    def create_user(self,email,name,password=None):
        """ Create new user Profile """

        if not email:
            raise ValueError('User must have an email address');

        email = self.normalize_email(email)
        user  = self.model(email=email,name=name)

        user.set_password(password)
        user.save(using=self._db)

        return user

    def create_superuser(self,email,name,password):
        """ Create new super user for system """

        user = self.create_user(email,name,password)

        user.is_superuser = True
        user.is_staff = True
        user.save(using=self._db)

        return user

# model
class userInfo(AbstractBaseUser,PermissionsMixin): 
    first_name = models.CharField(max_length=200)
    last_name = models.CharField(max_length=200)
    username = models.CharField(max_length=200)
    email = models.EmailField(max_length=200,verbose_name="email" , unique=True)
    # password = models.CharField(max_length=200) remove password it's created auto by Django so we don't need to add over here
    abn = models.CharField(max_length=200)
    # password = models.CharField(max_length=200) if you want to confirm password do it frontend side don't overhere because it will create extra field
    isActive = models.BooleanField(default=True) 
    created_date = models.DateTimeField(default=timezone.now)

    REQUIRED_FIELDS =['username']
    USERNAME_FIELD = 'email'
    objects = UserProfileManager() 
    class Meta:
       db_table="userInfo"

In View, You can able to access the permission method like


def register(request):

    if request.method == 'POST':
        first_name = request.POST['first_name']
        last_name = request.POST['last_name']
        username = request.POST['username']
        password1 = request.POST['password1']
        password2 = request.POST['password2']
        abn = request.POST['abn']
        email = request.POST['email']

        if password1==password2:
            if userInfo.objects.filter(username=username).exists():
                messages.info(request,'Username Taken')
                return redirect('register')
            elif userInfo.objects.filter(email=email).exists():
                messages.info(request,'Email Taken')
                return redirect('register')
            elif userInfo.objects.filter(abn=abn).exists():
                messages.info(request,'ABN Number Taken')
                return redirect('register')
            else:   
                user = userInfo.objects.create(username=username,email=email,first_name=first_name,last_name=last_name,abn=abn)
                user.set_password(password1) # using this method you will assing hashed password
                user.save()
                # user.id();  Foo.objects.latest('id')
                print('user created')
              #  return redirect('register')
                return redirect('sector')

        else:
            messages.info(request,'password not matching..')    
            return redirect('register')
        return redirect('/')
        
    else:
        return render(request,'assets/register.html')

def login(request):
    if request.method== 'POST':
        username = request.POST['username']
        password = request.POST['password']

        user = authenticate(username=username,password=password)

        if user is not None:
            auth.login(request, user)
            return redirect("/")
        else:
            messages.info(request,'invalid credentials')
            return redirect('login')

    else:
        return render(request,'assets/login.html')  

Here is link which might help User extending this site will help alot from learn simple is better then complex If you have any query let me know in comment

Seem you are missing user = userInfo.authenticate(username=username, password=password) for authentication in the register method. Example code:

def login(request):
    if request.method == 'POST':
        if request.is_ajax():
            username = request.POST.get('username', '')
            password = request.POST.get('password', '')

            user = authenticate(request, username=username, password=password)

            if user is not None:
                auth_login(request, user)
                response_data = {
                    'success': True
                }
            else:
                response_data = {
                    'success': False
                }
            return JsonResponse(response_data)
    else:
        return redirect('pages:home')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM