Home > Net >  django- login issue with AbstractBaseUser model
django- login issue with AbstractBaseUser model

Time:09-13

I've created the custom User model with AbstractBaseUser model. The creation of user works fine and i have checked on admin page.

But the problem is... when I try to log-in existing users from the custom User model, the username seem to validate from the database, but it doesn't seem to be able to bring or validate the password from the database.

here are my codes from my project.

models.py

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

# Create your models here.


class AccountManager(BaseUserManager):
    def create_user(self, email, username, password=None):
        if not email:
            raise ValueError("반드시 이메일 주소가 있어야 합니다.")
        if not username:
            raise ValueError("아이디는 반드시 있어야 합니다.")

        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=None):
        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 Member(AbstractBaseUser):
    MALE = 'M'
    FEMALE = 'F'
    GENDER_CHOICE = [ 
        (MALE, '남성'),
        (FEMALE, '여성'),
    ]

    YES = '동의'
    NO = '미동의'
    SMS_CHOICE = [ 
        (YES, '동의'),
        (NO, '미동의'),
    ]

    FOREIGNER = '외국인'
    NATIVE = '내국인'
    FOREIGN_CHECK = [ 
        (FOREIGNER, '외국인'),
        (NATIVE, '한국인'),
    ]


    no = models.CharField(verbose_name="스카이패스 회원번호", max_length=10, unique=True)
    username = models.CharField(verbose_name="회원 아이디", max_length=20, unique=True )
    password = models.CharField(verbose_name="비밀번호", max_length=500)
    date_joined = models.DateTimeField(verbose_name="회원가입 일자", auto_now_add=True)
    last_login = models.DateTimeField(verbose_name="마지막 로그인 시간", 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=10, verbose_name="이름", blank=True)
    last_name = models.CharField(max_length=10, verbose_name="성", blank=True)
    gender = models.CharField(verbose_name="성별", choices= GENDER_CHOICE, max_length=10)
    email = models.EmailField(verbose_name="이메일", max_length=60, unique=True)
    birthday = models.CharField(verbose_name='생년월일', default=None, max_length=100, null=True )
    phone = models.CharField(verbose_name='연락처', default=None, max_length=20, null=True)
    security1 = models.CharField(verbose_name="주민번호 앞자리", default=None, max_length=10, null=True, blank=True)
    security2 = models.CharField(verbose_name='주민번호 뒷자리', default=None, max_length=10, null=True, blank=True)
    sms = models.CharField(verbose_name="문자 수신 동의 여부", choices= SMS_CHOICE, default=None, max_length=10, null=True )
    check_foreign = models.CharField(verbose_name='외국인 여부 확인', choices= FOREIGN_CHECK, default=None, max_length=10, null=True)
    passport = models.CharField(verbose_name='여권번호', max_length=30, blank=True, null=True)
    p_points = models.IntegerField(verbose_name="잔여 포인트", default=0)



    USERNAME_FIELD = 'username' 
    REQUIRED_FIELDS = ['no', 'email' ]    

    objects = AccountManager 
    objects = UserManager()

    class Meta:
        db_table = 'member'


    def __str__(self):
        return self.last_name   ' '   self.first_name

    def has_perm(self, perm, ob=None):
        return self.is_admin

    def has_module_perms(self, app_label):
        return True

views.py

from django.shortcuts import render, redirect 
from django.contrib import messages
from django.http import HttpRequest
from django.contrib.auth import authenticate, login, logout
from register.models import Member
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, UserManager

# Create your views here.


def loginPage(request):
    global Member
    if request.method == "POST":
        username = request.POST.get('username')
        password = request.POST.get('password')
        print(username)
        print(password)
        try:
            user = Member.objects.get(username=username)
        except:
            messages.error(request, "username does not exist")

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

        if user is not None:
            login(request, user)
            return redirect('/')
        else:
            messages.error(request, "username or password does not exit.")

            

    context = {}
    return render(request, 'register/login.html', context)


def logoutUser(request):
    logout(request)
    return redirect('/')

login.html

{% extends 'layout/layout.html' %}

{% block content %}

<div>
    <form method="POST" action="">
        {% csrf_token %}
        <label>Username:</label>
        <input type="text" name="username" placeholder="Enter username" />

        <label>Password:</label>
        <input type="password" name="password" placeholder="Enter Password" />


        <input type="submit" value="Login"/>
    </form>
</div>
{% endblock %}

Please help me !!! I've been struggling with this for 2 days and I cannot find an answer to this issue from anywhere online.

CodePudding user response:

You can try to create a Django login form and authenticate the user in the clean function:

forms.py

class LoginForm(forms.Form):
    username = forms.CharField(max_length=100, label='사용자 이름')
    password = forms.CharField(max_length=100, label='단어', widget=forms.PasswordInput)

    def clean(self):
        username = self.cleaned_data.get('username')
        password = self.cleaned_data.get('password')
        if username and password:
            user = authenticate(username=username, password=password)
            if not user:
                raise forms.ValidationError("사용자 이름 또는 비밀번호를 잘못 입력했습니다!")
        return super(LoginForm, self).clean()

views.py

from .forms import LoginForm

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)

        return redirect('home')
    context = {"form": form}
    return render(request, 'register/login.html', context)

CodePudding user response:

UPDATE

so I finally solved this after days and hours of attempt.

As long as the AbstractBaseUser is set correctly , there are no other issues with that.

However, I had to import 'get_user_model' to bring the custom User model.

Simply, just put this on top of Views.py

from django.contrib.auth import get_user_model
from .models import "custom_user_name" #This is your own custom user name which you defined in models.py as class custom_user_name(AbstractBaseUser):

# write this too.
User = get_user_model()

There are tons of youtube videos to show you how to create custom User, but I could not find anyone who would show me how to import the custom user model.

I hope this saves time for whoever face this issue too.

  • Related