python - 自定义 Django 用户模型
问题描述
我只是尝试创建自己的自定义 Django 用户模型,但如果我尝试通过前端创建新用户,它会失败:
请求方法:POST 请求 URL: http: //127.0.0.1 :8000/signup/ Django 版本:2.1b1 异常类型:AttributeError 异常值:'Manager' 对象没有属性 'get_by_natural_key'
首先我创建了一个新的 Django 应用程序"accounts"
,然后我将以下内容添加到帐户应用程序的 models.py 中:
from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)
#User Model Manager
class UserManager(BaseUserManager):
def create_user(self, username, password=None):
"""
Creates and saves a User with the given username and password.
"""
if not username:
raise ValueError('Error: The User you want to create must have an username, try again')
user = self.model(
user=self.normalize_username(username),
)
user.set_password(password)
user.save(using=self._db)
return user
def create_staffuser(self, username, password):
"""
Creates and saves a staff user with the given username and password.
"""
user = self.create_user(
username,
password=password,
)
user.staff = True
user.save(using=self._db)
return user
def create_superuser(self, username, password):
"""
Creates and saves a superuser with the given username and password.
"""
user = self.create_user(
username,
password=password,
)
user.staff = True
user.admin = True
user.save(using=self._db)
return user
class User(AbstractBaseUser):
user = models.CharField(
verbose_name='username',
max_length=30,
unique=True,
)
active = models.BooleanField(default=True)
staff = models.BooleanField(default=False) # a admin user; non super-user
admin = models.BooleanField(default=False) # a superuser
# notice the absence of a "Password field", that's built in.
USERNAME_FIELD = 'user'
REQUIRED_FIELDS = [] # Username & Password are required by default.
def get_full_name(self):
# The user is identified by their Username address
return self.user
def get_short_name(self):
# The user is identified by their Username address
return self.user
def __str__(self): # __unicode__ on Python 2
return self.user
def has_perm(self, perm, obj=None):
"""Does the user have a specific permission?"""
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"""Does the user have permissions to view the app `app_label`?"""
# Simplest possible answer: Yes, always
return True
@property
def is_staff(self):
"""Is the user a member of staff?"""
return self.staff
@property
def is_admin(self):
"""Is the user a admin member?"""
return self.admin
@property
def is_active(self):
"""Is the user active?"""
return self.active
我的实际博客应用程序的model.py:
from django.db import models
from django.utils import timezone
from smartfields import fields
from smartfields.dependencies import FileDependency
from smartfields.processors import ImageProcessor
# Categorys of Post Model
class Category(models.Model):
title = models.CharField(max_length=255, verbose_name="Title")
description = models.TextField(max_length=1000, null=True, blank=True)
cover = fields.ImageField(upload_to='categorycovers/', blank=True, null=True, dependencies=[
FileDependency(processor=ImageProcessor(
format='JPEG', scale={'max_width': 350, 'max_height': 350}))
])
icon = fields.ImageField(upload_to='categoryicons/', blank=True, null=True, dependencies=[
FileDependency(processor=ImageProcessor(
format='JPEG', scale={'max_width': 16, 'max_height': 16}))
])
class Meta:
verbose_name = "Category"
verbose_name_plural = "Categories"
ordering = ['title']
def __str__(self):
return self.title
#Post Model
class Post(models.Model):
author = models.ForeignKey('accounts.User', on_delete=models.CASCADE)
title = models.CharField(max_length=75)
content = models.TextField(max_length=10000)
tag = models.CharField(max_length=50, blank=True)
category = models.ForeignKey(Category, verbose_name="Category", on_delete=models.CASCADE, null=True)
postattachment = fields.FileField(upload_to='postattachment/%Y/%m/%d/', blank=True ,null=True)
postcover = fields.ImageField(upload_to='postcover/%Y/%m/%d/', null=True, dependencies=[
FileDependency(processor=ImageProcessor(
format='JPEG', scale={'max_width': 200, 'max_height': 200}))
])
created_date = models.DateField(auto_now_add=True)
published_date = models.DateField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
class Meta:
ordering = ["-title"]
def __str__(self):
return self.title
#Comment(s) of Post Model
class Comment(models.Model):
author = models.ForeignKey('accounts.User', on_delete=models.CASCADE)
post=models.ForeignKey(Post, on_delete=models.CASCADE)
content = models.TextField()
created_date = models.DateField(default=timezone.now)
published_date = models.DateField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.text
之后我跳回 settings.py 并将自定义用户模型添加到我的实际博客应用程序中:
AUTH_USER_MODEL = 'accounts.User'
我还添加了
INSTALLED_APPS = [
...
'accounts',
...
]
我不希望我的用户有任何电子邮件地址。我只是希望他们通过用户名进行身份验证...
有什么提示吗?谢谢 :)
解决方案
DjangoAbstractBaseUser
类没有字段username
在您的声明中,您声明了一个用户名字段并将其命名user
但是USERNAME_FIELD
是username
像这样改变你的模型
class User(AbstractBaseUser):
user = models.CharField(
verbose_name='username',
max_length=30,
unique=True,
)
active = models.BooleanField(default=True)
staff = models.BooleanField(default=False) # a admin user; non super-user
admin = models.BooleanField(default=False) # a superuser
USERNAME_FIELD = 'user'
REQUIRED_FIELDS = [] # Username & Password are required by default.
...
您也可以将用户模型中的用户字段重命名为用户名并解决问题。
推荐阅读
- thread-safety - 如何确定哪些 Allegro 库函数是线程安全的?
- docker - Alpine Docker CMD 未按预期启动 crond
- reactjs - 如何正确组合具有无限滚动逻辑的功能组件
- geospatial - 将 rioxarray 剪辑到 shapefile 时出现 CRS 错误
- html - 如何强制 flexbox 中的 div 不展开?
- go - 如何使用 gin 作为服务器来编写 prometheus 导出器指标
- java - 如何使用 javax.xml.bind.annotation 在 java 中添加空白命名空间
- swiftui - SwiftUI 在列表的单元格视图中更新observedObject
- nginx - Nginx - 反向代理所有以关键字开头的请求
- swift - 当我的文档目录中没有可用数据时,想要快速向用户显示一条消息