无法验证自定义用户

时间:2019-06-26 17:15:00

标签: django python-3.x

我对Django比较陌生。 我有一个Web应用程序(正在开发中),该应用程序使用名为User的自定义用户模型,然后由3个子类继承:Contractor,Supervisor和Client,它提供了3种用户类型。 我可以很好地创建所有三种类型的用户,也可以使用管理站点来查看/编辑/删除它们。 然而。当我尝试使用各自的凭据分别作为客户端和主管登录时,收到错误的电子邮件/密码错误。奇怪的是,当我使用承包商的电子邮件/密码登录时,不会发生此错误。 我无法真正弄清问题是什么,因此无法真正解决问题。如果有人可以指出我必须犯的错误,那就太好了。

models.py:

from django.db import models
from django.contrib.auth.models import AbstractUser, AbstractBaseUser
from django_countries.fields import CountryField
from django.contrib.auth.base_user import BaseUserManager
from myproject import settings


# Create your models here.

class UserAccountManager(BaseUserManager):
    def create_user(self, email, password=None):
        if not email:
            raise ValueError('Email must be set!')
        user = self.model(email=self.normalize_email(email),
                          )
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password):
        user = self.create_user(email, password)
        user.is_admin = True
        user.is_staff = True
        user.is_superuser = True
        user.save(using = self._db)
        return user

class User(AbstractBaseUser):
    email = models.EmailField(max_length=150, unique=True)
    is_client = models.BooleanField(default=False)
    is_contractor = models.BooleanField(default=False)
    is_supervisor = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=False)
    username = models.CharField(max_length=150, blank=True)
    is_superuser = True


    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = UserAccountManager()

    def has_perm(self, perm, obj=None):
        return self.is_superuser

    def has_module_perms(self, users):
        return self.is_superuser

class Client(User):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, parent_link=True)
    name = models.CharField(max_length=150, verbose_name='Name')
    address_1 = models.CharField(max_length=150, verbose_name='Address')
    address_2 = models.CharField(max_length=150, blank=True, verbose_name='Address (#2)', null=True)
    country = CountryField()
    region = models.CharField(max_length=150, blank=True, verbose_name='Region')
    city = models.CharField(max_length=150, verbose_name='City')
    postal_code = models.CharField(max_length=150, verbose_name='Postal code')
    po_box_no = models.IntegerField(blank=True, verbose_name='P.O. Box no', null=True)
    landline_no = models.IntegerField(verbose_name='Landline number')
    mobile_no_1 = models.IntegerField(verbose_name='Mobile number')
    mobile_no_2 = models.IntegerField(blank=True, verbose_name='Mobile number (#2)', null=True)
    bank_name_1 = models.CharField(max_length=150, verbose_name="Bank name")
    bank_account_no_1 = models.CharField(max_length=150, verbose_name='Bank account number')
    bank_name_2 = models.CharField(max_length=150, blank=True, verbose_name="Bank name (#2)", null=True)
    bank_account_no_2 = models.CharField(max_length=150, blank=True, verbose_name = 'Bank account number (#2)', null=True)
    national_id = models.IntegerField(verbose_name='National I.D.')
    zip_code = models.IntegerField(verbose_name='ZIP Code', blank=True, null=True)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)


    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = [
        'name', 'address_1', 'country', 'city', 'postal_code', 'landline_no', 'username',
        'mobile_no_1', 'bank_name_1', 'bank_account_no_1', 'national_id', 'zip_code',
        ]

    def __str__(self):
        return self.email


    class Meta:
        verbose_name = 'client'
        verbose_name_plural = 'clients'


class Contractor(User):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, parent_link=True)
    name = models.CharField(max_length=150, verbose_name='Name')
    address_1 = models.CharField(max_length=150, verbose_name='Address')
    address_2 = models.CharField(max_length=150, blank=True, verbose_name='Address (#2)', null=True)
    country = CountryField()
    region = models.CharField(max_length=150, blank=True, verbose_name='Region')
    city = models.CharField(max_length=150, verbose_name='City')
    postal_code = models.CharField(max_length=150, verbose_name='Postal code')
    po_box_no = models.IntegerField(blank=True, verbose_name='P.O. Box no', null=True)
    landline_no = models.IntegerField(verbose_name='Work phone number')
    mobile_no_1 = models.IntegerField(verbose_name='Mobile number')
    mobile_no_2 = models.IntegerField(blank=True, verbose_name='Mobile number (#2)', null=True)
    bank_name_1 = models.CharField(max_length=150, verbose_name="Bank name")
    bank_account_no_1 = models.CharField(max_length=150, verbose_name='Bank account number')
    bank_name_2 = models.CharField(max_length=150, blank=True, verbose_name="Bank name (#2)", null=True)
    bank_account_no_2 = models.CharField(max_length=150, blank=True, verbose_name = 'Bank account number (#2)', null=True)
    national_id = models.IntegerField(verbose_name='National I.D.')
    zip_code = models.IntegerField(verbose_name='ZIP Code', blank=True, null=True)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)


    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = [
        'name', 'address_1', 'country', 'city', 'postal_code', 'landline_no', 'username',
        'mobile_no_1', 'bank_name_1', 'bank_account_no_1', 'national_id', 'zip_code',
        ]

    def __str__(self):
        return self.email

    class Meta:
        verbose_name = 'contractor'
        verbose_name_plural = 'contractors'

class Supervisor(User):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, parent_link=True)
    name = models.CharField(max_length=150, verbose_name='Name')
    address_1 = models.CharField(max_length=150, verbose_name='Address')
    address_2 = models.CharField(max_length=150, blank=True, verbose_name='Address (#2)', null=True)
    country = CountryField()
    region = models.CharField(max_length=150, blank=True, verbose_name='Region')
    city = models.CharField(max_length=150, verbose_name='City')
    postal_code = models.CharField(max_length=150, verbose_name='Postal code')
    po_box_no = models.IntegerField(blank=True, verbose_name='P.O. Box no', null=True)
    landline_no = models.IntegerField(verbose_name='Work number')
    mobile_no_1 = models.IntegerField(verbose_name='Mobile number')
    mobile_no_2 = models.IntegerField(blank=True, verbose_name='Mobile number (#2)', null=True)
    bank_name_1 = models.CharField(max_length=150, verbose_name="Bank name")
    bank_account_no_1 = models.CharField(max_length=150, verbose_name='Bank account number')
    bank_name_2 = models.CharField(max_length=150, blank=True, verbose_name="Bank name (#2)", null=True)
    bank_account_no_2 = models.CharField(max_length=150, blank=True, verbose_name = 'Bank account number (#2)', null=True)
    national_id = models.IntegerField(verbose_name='National I.D.')
    zip_code = models.IntegerField(verbose_name='ZIP Code', blank=True, null=True)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)


    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = [
        'name', 'address_1', 'country', 'city', 'postal_code', 'landline_no', 'username',
        'mobile_no_1', 'bank_name_1', 'bank_account_no_1', 'national_id', 'zip_code',
        ]

    def __str__(self):
        return self.email

    class Meta:
        verbose_name = 'supervisor'
        verbose_name_plural = 'supervisors'

views.py:

    # Create your views here.

    from django.shortcuts import render

    from django.contrib.auth import login
    from django.shortcuts import redirect
    from django.views.generic import CreateView


    from .forms import ClientSignUp, ContractorSignUp, SupervisorSignUp
    from .models import Client, Contractor, Supervisor
    from decorators import *

    from django.utils.decorators import method_decorator
    from django.contrib.auth.decorators import login_required


    class ClientSignUpView(CreateView):
        model = Client
        form_class = ClientSignUp
        template_name = 'registration/signup_form.html'

        def get_context_data(self, **kwargs):
            kwargs['user_type'] = 'client'
            return super().get_context_data(**kwargs)

        def form_valid(self, form):
            user = form.save()
            user.set_password('raw_password')
            user.save()
            login(self.request, user)
            return redirect('accounts/profile')



    class ContractorSignUpView(CreateView):
        model = Contractor
        form_class = ContractorSignUp
        template_name = 'registration/signup_form.html'

        def get_context_data(self, **kwargs):
            kwargs['user_type'] = 'contractor'
            return super().get_context_data(**kwargs)

        def form_valid(self, form):
            user = form.save()
            user.save()
            user.set_password('raw_password')
            login(self.request, user)
            return redirect('accounts/profile')

    class SupervisorSignUpView(CreateView):
        model = Supervisor
        form_class = SupervisorSignUp
        template_name = 'registration/signup_form.html'

        def get_context_data(self, **kwargs):
            kwargs['user_type'] = 'supervisor'
            return super().get_context_data(**kwargs)

        def form_valid(self, form):
            if form.is_valid():
                user = form.save()
                user.set_password('raw_password')
                user.save()
                login(self.request, user)
                return redirect('accounts/profile')

EmailBackend.py:

    from django.contrib.auth.backends import ModelBackend
    from users.models import User

    class Email_backend(object):
        def authenticate(self, username=None, password=None):
            try:
                user=User.objects.get(email=username)
            except User.DoesNotExist:
                return None

            if check_password(password, user.password):
                return user
            return None

        def get_user(self, user_id):
            try:
                return User.objects.get(pk=user_id)
            except User.DoesNotExist:
                return None

login.html:

    {% extends 'base.html' %}

{% block title %}Login{% endblock %}

{% block content %}
  <h2>Login</h2>
  <form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Login</button>
  </form>

{% endblock %}

0 个答案:

没有答案