Django中的用户模型继承和扩展

发布于 2024-12-12 10:01:10 字数 228 浏览 1 评论 0原文

我想从内置类 User 继承 UserProfile 类,并进行 2 处修改:

1)用户名字段必须不唯一

2)电子邮件字段必须唯一

那么,如何通过 UserProfile 类覆盖这 2 个字段?

据我了解,我无法更改 User 类,所以我必须以某种方式在 UserProfile 类中进行此更改...... 但如何做到这一点??? 请帮助我!

提前致谢!!!!

I want to inherit UserProfile class from builtin class User with 2 modifications:

1) username field must be not unique

2) email field must be unique

So, how to override this 2 fields by UserProfile class?

As I understand I can't change class User, so I must do this changes in class UserProfile somehow...
But how to do that???
Help me please!

Thanks in advance!!!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

柏林苍穹下 2024-12-19 10:01:10

我认为你应该只是猴子补丁。

我自己从未这样做过,但深入研究这一点很有趣。查看模型字段初始化函数(我们需要在其中传递 unique=True),

def __init__(self, verbose_name=None, name=None, primary_key=False,
        max_length=None, unique=False, blank=False, null=False,
        db_index=False, rel=None, default=NOT_PROVIDED, editable=True,
        serialize=True, unique_for_date=None, unique_for_month=None,
        unique_for_year=None, choices=None, help_text='', db_column=None,
        db_tablespace=None, auto_created=False, validators=[],
        error_messages=None):
    self.name = name
    self.verbose_name = verbose_name
    self.primary_key = primary_key
    self.max_length, self._unique = max_length, unique

它似乎只关心属性 _unique 是 True 还是 False。 Django 魔法的其余部分不应该关心该属性是如何设置的,所以让我们来猴子补丁吧!

将猴子补丁应用程序放在 INSTALLED_APPS 中的某个位置,然后将其放入 models.py (自动加载):

from django.contrib.auth.models import User
User._meta.get_field("username")._unique = False
User._meta.get_field("email")._unique = True

果然,django 生成以下 SQL:

CREATE TABLE "auth_user" (
    "id" integer NOT NULL PRIMARY KEY,
    "username" varchar(30) NOT NULL,
    "first_name" varchar(30) NOT NULL,
    "last_name" varchar(30) NOT NULL,
    "email" varchar(75) NOT NULL UNIQUE,
    "password" varchar(128) NOT NULL,
    "is_staff" bool NOT NULL,
    "is_active" bool NOT NULL,
    "is_superuser" bool NOT NULL,
    "last_login" datetime NOT NULL,
    "date_joined" datetime NOT NULL
)

I think you should just monkey patch.

I've never done this myself, but it was fun digging into this. Check out the model field init function (where we'd need to pass unique=True)

def __init__(self, verbose_name=None, name=None, primary_key=False,
        max_length=None, unique=False, blank=False, null=False,
        db_index=False, rel=None, default=NOT_PROVIDED, editable=True,
        serialize=True, unique_for_date=None, unique_for_month=None,
        unique_for_year=None, choices=None, help_text='', db_column=None,
        db_tablespace=None, auto_created=False, validators=[],
        error_messages=None):
    self.name = name
    self.verbose_name = verbose_name
    self.primary_key = primary_key
    self.max_length, self._unique = max_length, unique

All it seems to care about is that an attribute _unique is True or False. The rest of django magic shouldn't care how that attribute was set, so let's monkey patch!

Put a monkey patch app somewhere in your INSTALLED_APPS, and put this in your models.py (which is auto loaded):

from django.contrib.auth.models import User
User._meta.get_field("username")._unique = False
User._meta.get_field("email")._unique = True

Sure enough, django generates the following SQL:

CREATE TABLE "auth_user" (
    "id" integer NOT NULL PRIMARY KEY,
    "username" varchar(30) NOT NULL,
    "first_name" varchar(30) NOT NULL,
    "last_name" varchar(30) NOT NULL,
    "email" varchar(75) NOT NULL UNIQUE,
    "password" varchar(128) NOT NULL,
    "is_staff" bool NOT NULL,
    "is_active" bool NOT NULL,
    "is_superuser" bool NOT NULL,
    "last_login" datetime NOT NULL,
    "date_joined" datetime NOT NULL
)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文