Я новичок в Django, и я впервые создаю веб-приложение с использованием фреймворка.Мое веб-приложение имеет 3 типа пользователей: клиент, руководитель и подрядчик.Эти 3 пользователя подключены к пользовательской модели пользователя через OneToOneField, которая называется «пользователь».(Мои пользовательские подклассы модели пользователя AbstractBaseUser) Я создал таблицы базы данных и выполнил миграцию, сделал все начальные задачи и т. Д., Но когда я пытаюсь создать пользователя клиента (который подклассы models.Model) для моего веб-приложения,Я получаю следующий AttributeError: «Клиентский» объект не имеет атрибута «set_password».
Я видел некоторые решения, которые предлагают либо определить свой собственный атрибут set_password (будь то у models.Model такого атрибута нет), либо создать подкласс класса AbstractBaseUser.Я хотел бы попробовать первый вариант, однако, я немного озадачен тем, как определить атрибут 'set_password' для моей модели.PS: пожалуйста, не стесняйтесь указывать на любые другие ошибки в моем коде.
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(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=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)')
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')
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)')
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)")
bank_account_no_2 = models.CharField(max_length=150, blank=True, verbose_name = 'Bank account number (#2)')
email = models.EmailField(max_length=150, unique=True, verbose_name = 'E-mail')
username = models.CharField(max_length=150, blank=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', 'region', 'postal_code',
'po_box_no', 'landline_no', 'mobile_no_1', 'email',
'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'
def save(self, *args, **kwargs):
if not self.pk:
try:
p = Client.objects.get(email=self.email)
self.pk=p.pk
except Client.DoesNotExist:
pass
super(Client, self).save(*args, **kwargs)
views.py:
from django.shortcuts import render
# Create your views here.
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
##@method_decorator([login_required, client_required], name='dispatch')
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.save()
login(self.request, user)
return redirect('accounts/profile')
forms.py:
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import Client, Contractor, Supervisor
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.forms import EmailField
from django.utils.translation import ugettext_lazy as _
import logging
log = logging.getLogger(__name__)
from django.utils.encoding import force_text
from django.db import transaction
# -----------------------------------
# CLIENT SIGNUP FORM
class ClientSignUp(UserCreationForm):
email = EmailField(label=_("Email address"), required=True)
class Meta(UserCreationForm):
model = Client
fields = ('email', 'name', 'address_1', 'address_2', 'country', 'city', 'region', 'postal_code',
'po_box_no', 'landline_no', 'username', 'mobile_no_1', 'mobile_no_2',
'bank_name_1', 'bank_account_no_1', 'bank_name_2', 'bank_account_no_2', 'national_id', 'zip_code',
)
@transaction.atomic
def save(self, commit=True):
user = super().save(commit=False)
user.is_client = True
user.email = self.cleaned_data["email"]
if commit:
user.save()
return user