我正在尝试学习Django,我希望得到任何拥有MVC / MTV / PHP / Ruby框架经验的人的反馈。有没有人发现用户模型与auth紧密耦合?
背景:当您第一次为Django实现身份验证时,您包含模块django.contrib.auth
这将引入一些模型,如用户,群组,消息等。让我们关注用户模型,因为这是任何网站中最重要的表格之一。
简而言之,User表包含这些字段
用户
目标:
我想删除用户名并使用电子邮件作为每个用户的登录信息。这是一个非常简单的请求,很多网站都使用这些日子。
我不想修补核心代码,因为这会使升级更加困难。这意味着修改用户模型是不可能的。我只想做一些简单和基本的事情,我希望有一些框架可以做,所以让我来解决Django如何做到这一点。
向用户模型添加新字段
Django docs说使用创建另一个表并在那里插入字段。您将在User表和Profile表之间建立一对一的关系。 例如。 如果要向每个用户添加图像字段,请将其添加到配置文件表中。每次都会进行连接查询。他们甚至指定了一个常量来告诉框架使用哪个表: AUTH_PROFILE_MODULE ='accounts.UserProfile' 我不认为每次我想要一个属于用户表的字段时都必须进行连接查询。
另一种选择是使用add_to_class函数。 django社区已经声明在主类之外定义新字段并不好,因为添加方法的其他开发人员不会知道所有数据成员。
修改旧字段
auth模块检查两个字段的用户名和哈希密码。查看上表,我需要更改用户名模型以接受这些属性。长度为75,包含电子邮件的所有有效字符。 django建议我查看电子邮件字段。
如果我使用电子邮件字段进行身份验证,则会出现两个问题: 我需要编写一个新类,用于常量AUTHENTICATION_BACKEND,因此它会检查电子邮件字段,并且我有一个名为username的未使用字段。
添加新方法
在MVC / MTV中,设计原则是使用胖模型瘦控制器。由于模型是在auth中声明的,我不确定应该如何添加对用户模型字段起作用的方法。由于django建议使用Profile模型,我想他们必须去那里。
扩展用户类
小烦恼是我不能使用“用户”这个名称,而必须使用“用户”或“帐户”。更大的一个是我认为auth不会识别这个新模块。意思是我必须重写一堆存在的功能。这个不会打扰我,因为这是我期望在其他框架中做的事情。
任何评论都表示赞赏。如果我对使用django不感兴趣,我不会问所有这些问题并寻找解决方案。
答案 0 :(得分:4)
我同意django对auth模型的持续不懈是荒谬的。我的工作要求我创建超可扩展且非常高负载的站点,有时需要用户身份验证,djano的auth模型+权限不适合。
幸运的是,替换并不困难。
首先,创建一个自定义用户模型。
class User(models.Model):
...fields...
#Define some interface methods to be compatible.
def get_and_delete_messages(self):
def is_active(self):
def is_anonymous(self):
def is_authenticated(self):
def is_staff(self):
def has_perm(self, perm_list):
其次,创建自己的身份验证后端。
class LocalAccount(object):
"""
This checks our local user DB for authentication
"""
def authenticate(self, username=None, password=None):
try:
user = User.objects.get(alias=username)
if user.check_password(password):
return user
except User.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.select_related().get(pk=user_id)
except User.DoesNotExist:
return None
#settings.py
AUTHENTICATION_BACKENDS = (
'helpers.auth.LocalAccount',
)
这应该解决你的大多数问题,我甚至不认为你在django.contrib.auth.User上找到的所有方法都是必要的,我建议你尝试一下。
这里的问题是管理员可能会开始讨厌,幸运的是,使用简单的python继承也很容易修补。这是另一个问题:)
答案 1 :(得分:1)
在一天结束时,您的项目的auth后端需要某种存储来获取身份验证凭据。在这方面,默认 auth后端紧密耦合到User
模型并不奇怪。如果您编写自己的身份验证后端({3}},则很容易将自己的定义替换为用户模型。
答案 2 :(得分:0)
我创建了我的Profile模型并使用AUTH_PROFILE_MODULE,所以我可以完全控制我的模型,我可以修改字段,添加方法等等。现在我正在考虑使用缓存和编写中间件,如果可能的话,将从缓存中获取配置文件
要使用电子邮件登录,您可以编写非常简单的身份验证后端:
from django.contrib.auth.models import User
from django.contrib.auth.backends import ModelBackend
class EmailModelBackend(ModelBackend):
def authenticate(self, username=None, password=None):
try:
user = User.objects.get(email=username)
if user.check_password(password):
return user
except User.DoesNotExist:
return None