在 Django 中扩展用户模型的最佳方法是什么?

发布于 2024-07-04 22:28:00 字数 359 浏览 6 评论 0 原文

使用自定义字段扩展用户模型(与 Django 的身份验证应用程序捆绑在一起)的最佳方法是什么? 我也可能想使用电子邮件作为用户名(用于身份验证目的)。

我已经见过很少< /a> 方法去做,但无法决定哪一个是最好的。

What's the best way to extend the User model (bundled with Django's authentication app) with custom fields? I would also possibly like to use the email as the username (for authentication purposes).

I've already seen a few ways to do it, but can't decide on which one is the best.

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

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

发布评论

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

评论(17

厌倦 2024-07-11 22:28:00

注意:此答案已被弃用。 如果您使用的是 Django 1.7 或更高版本,请参阅其他答案。

这就是我的做法。

#in models.py
from django.contrib.auth.models import User
from django.db.models.signals import post_save

class UserProfile(models.Model):  
    user = models.OneToOneField(User)  
    #other fields here

    def __str__(self):  
          return "%s's profile" % self.user  

def create_user_profile(sender, instance, created, **kwargs):  
    if created:  
       profile, created = UserProfile.objects.get_or_create(user=instance)  

post_save.connect(create_user_profile, sender=User) 

#in settings.py
AUTH_PROFILE_MODULE = 'YOURAPP.UserProfile'

如果创建的话,每次保存用户时都会创建一个用户配置文件。
然后,您可以使用

  user.get_profile().whatever

以下是文档中的更多信息

http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users

更新:请注意AUTH_PROFILE_MODULE 自 v1.5 起已弃用: https:// /docs.djangoproject.com/en/1.5/ref/settings/#auth-profile-module

Note: this answer is deprecated. see other answers if you are using Django 1.7 or later.

This is how I do it.

#in models.py
from django.contrib.auth.models import User
from django.db.models.signals import post_save

class UserProfile(models.Model):  
    user = models.OneToOneField(User)  
    #other fields here

    def __str__(self):  
          return "%s's profile" % self.user  

def create_user_profile(sender, instance, created, **kwargs):  
    if created:  
       profile, created = UserProfile.objects.get_or_create(user=instance)  

post_save.connect(create_user_profile, sender=User) 

#in settings.py
AUTH_PROFILE_MODULE = 'YOURAPP.UserProfile'

This will create a userprofile each time a user is saved if it is created.
You can then use

  user.get_profile().whatever

Here is some more info from the docs

http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users

Update: Please note that AUTH_PROFILE_MODULE is deprecated since v1.5: https://docs.djangoproject.com/en/1.5/ref/settings/#auth-profile-module

沙沙粒小 2024-07-11 22:28:00

2008 年已经过去了一段时间,是时候给出一些新的答案了。 从 Django 1.5 开始,您将能够创建自定义 User 类。 实际上,在我写这篇文章的时候,它已经合并到 master 中了,所以你可以尝试一下。

docs 中有一些关于它的信息,或者如果您想挖掘的话更深入地了解它,在此提交中。

您所要做的就是将 AUTH_USER_MODEL 添加到带有自定义用户类路径的设置中,该类扩展了 AbstractBaseUser (更可自定义的版本)或 AbstractUser (您可以扩展或多或少的旧用户类)。

对于那些懒得点击的人,这里是代码示例(取自 docs ):

from django.db import models
from django.contrib.auth.models import (
    BaseUserManager, AbstractBaseUser
)


class MyUserManager(BaseUserManager):
    def create_user(self, email, date_of_birth, password=None):
        """
        Creates and saves a User with the given email, date of
        birth and password.
        """
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=MyUserManager.normalize_email(email),
            date_of_birth=date_of_birth,
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, username, date_of_birth, password):
        """
        Creates and saves a superuser with the given email, date of
        birth and password.
        """
        u = self.create_user(username,
                        password=password,
                        date_of_birth=date_of_birth
                    )
        u.is_admin = True
        u.save(using=self._db)
        return u


class MyUser(AbstractBaseUser):
    email = models.EmailField(
                        verbose_name='email address',
                        max_length=255,
                        unique=True,
                    )
    date_of_birth = models.DateField()
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = MyUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['date_of_birth']

    def get_full_name(self):
        # The user is identified by their email address
        return self.email

    def get_short_name(self):
        # The user is identified by their email address
        return self.email

    def __unicode__(self):
        return self.email

    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?"
        # Simplest possible answer: All admins are staff
        return self.is_admin

Well, some time passed since 2008 and it's time for some fresh answer. Since Django 1.5 you will be able to create custom User class. Actually, at the time I'm writing this, it's already merged into master, so you can try it out.

There's some information about it in docs or if you want to dig deeper into it, in this commit.

All you have to do is add AUTH_USER_MODEL to settings with path to custom user class, which extends either AbstractBaseUser (more customizable version) or AbstractUser (more or less old User class you can extend).

For people that are lazy to click, here's code example (taken from docs):

from django.db import models
from django.contrib.auth.models import (
    BaseUserManager, AbstractBaseUser
)


class MyUserManager(BaseUserManager):
    def create_user(self, email, date_of_birth, password=None):
        """
        Creates and saves a User with the given email, date of
        birth and password.
        """
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=MyUserManager.normalize_email(email),
            date_of_birth=date_of_birth,
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, username, date_of_birth, password):
        """
        Creates and saves a superuser with the given email, date of
        birth and password.
        """
        u = self.create_user(username,
                        password=password,
                        date_of_birth=date_of_birth
                    )
        u.is_admin = True
        u.save(using=self._db)
        return u


class MyUser(AbstractBaseUser):
    email = models.EmailField(
                        verbose_name='email address',
                        max_length=255,
                        unique=True,
                    )
    date_of_birth = models.DateField()
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = MyUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['date_of_birth']

    def get_full_name(self):
        # The user is identified by their email address
        return self.email

    def get_short_name(self):
        # The user is identified by their email address
        return self.email

    def __unicode__(self):
        return self.email

    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?"
        # Simplest possible answer: All admins are staff
        return self.is_admin
浪漫人生路 2024-07-11 22:28:00

从 Django 1.5 开始,您可以轻松扩展用户模型并在数据库中保留单个表。

from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import ugettext_lazy as _

class UserProfile(AbstractUser):
    age = models.PositiveIntegerField(_("age"))

您还必须在设置文件中将其配置为当前用户类别。

# supposing you put it in apps/profiles/models.py
AUTH_USER_MODEL = "profiles.UserProfile"

如果您想添加大量用户的首选项,OneToOneField 选项可能是更好的选择。

开发第三方库的人员请注意:如果您需要访问用户类,请记住人们可以更改它。 使用官方助手获取正确的类

from django.contrib.auth import get_user_model

User = get_user_model()

Since Django 1.5 you may easily extend the user model and keep a single table on the database.

from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import ugettext_lazy as _

class UserProfile(AbstractUser):
    age = models.PositiveIntegerField(_("age"))

You must also configure it as current user class in your settings file

# supposing you put it in apps/profiles/models.py
AUTH_USER_MODEL = "profiles.UserProfile"

If you want to add a lot of users' preferences the OneToOneField option may be a better choice thought.

A note for people developing third party libraries: if you need to access the user class remember that people can change it. Use the official helper to get the right class

from django.contrib.auth import get_user_model

User = get_user_model()
千年*琉璃梦 2024-07-11 22:28:00

每次创建用户时创建一个新条目来简单地扩展用户配置文件。

您可以通过使用 Django post save signal models.py

from django.db.models.signals import *
from __future__ import unicode_literals

class UserProfile(models.Model):

    user_name = models.OneToOneField(User, related_name='profile')
    city = models.CharField(max_length=100, null=True)

    def __unicode__(self):  # __str__
        return unicode(self.user_name)

def create_user_profile(sender, instance, created, **kwargs):
    if created:
        userProfile.objects.create(user_name=instance)

post_save.connect(create_user_profile, sender=User)

这将在创建新用户时自动创建一个员工实例。

如果您希望扩展用户模型并希望在创建用户时添加更多信息,您可以使用 django-betterforms (http://django-betterforms.readthedocs.io/en/latest/multiform.html)。 这将创建一个用户添加表单,其中包含 UserProfile 模型中定义的所有字段。

models.py

from django.db.models.signals import *
from __future__ import unicode_literals

class UserProfile(models.Model):

    user_name = models.OneToOneField(User)
    city = models.CharField(max_length=100)

    def __unicode__(self):  # __str__
        return unicode(self.user_name)

forms.py

from django import forms
from django.forms import ModelForm
from betterforms.multiform import MultiModelForm
from django.contrib.auth.forms import UserCreationForm
from .models import *

class ProfileForm(ModelForm):

    class Meta:
        model = Employee
        exclude = ('user_name',)


class addUserMultiForm(MultiModelForm):
    form_classes = {
        'user':UserCreationForm,
        'profile':ProfileForm,
    }

视图.py

from django.shortcuts import redirect
from .models import *
from .forms import *
from django.views.generic import CreateView

class AddUser(CreateView):
    form_class = AddUserMultiForm
    template_name = "add-user.html"
    success_url = '/your-url-after-user-created'

    def form_valid(self, form):
        user = form['user'].save()
        profile = form['profile'].save(commit=False)
        profile.user_name = User.objects.get(username= user.username)
        profile.save()
        return redirect(self.success_url)

addUser.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="." method="post">
            {% csrf_token %}
            {{ form }}     
            <button type="submit">Add</button>
        </form>
     </body>
</html>

urls.py

from django.conf.urls import url, include
from appName.views import *
urlpatterns = [
    url(r'^add-user/
, AddUser.as_view(), name='add-user'),
]

You can Simply extend user profile by creating a new entry each time when a user is created by using Django post save signals

models.py

from django.db.models.signals import *
from __future__ import unicode_literals

class UserProfile(models.Model):

    user_name = models.OneToOneField(User, related_name='profile')
    city = models.CharField(max_length=100, null=True)

    def __unicode__(self):  # __str__
        return unicode(self.user_name)

def create_user_profile(sender, instance, created, **kwargs):
    if created:
        userProfile.objects.create(user_name=instance)

post_save.connect(create_user_profile, sender=User)

This will automatically create an employee instance when a new user is created.

If you wish to extend user model and want to add further information while creating a user you can use django-betterforms (http://django-betterforms.readthedocs.io/en/latest/multiform.html). This will create a user add form with all fields defined in the UserProfile model.

models.py

from django.db.models.signals import *
from __future__ import unicode_literals

class UserProfile(models.Model):

    user_name = models.OneToOneField(User)
    city = models.CharField(max_length=100)

    def __unicode__(self):  # __str__
        return unicode(self.user_name)

forms.py

from django import forms
from django.forms import ModelForm
from betterforms.multiform import MultiModelForm
from django.contrib.auth.forms import UserCreationForm
from .models import *

class ProfileForm(ModelForm):

    class Meta:
        model = Employee
        exclude = ('user_name',)


class addUserMultiForm(MultiModelForm):
    form_classes = {
        'user':UserCreationForm,
        'profile':ProfileForm,
    }

views.py

from django.shortcuts import redirect
from .models import *
from .forms import *
from django.views.generic import CreateView

class AddUser(CreateView):
    form_class = AddUserMultiForm
    template_name = "add-user.html"
    success_url = '/your-url-after-user-created'

    def form_valid(self, form):
        user = form['user'].save()
        profile = form['profile'].save(commit=False)
        profile.user_name = User.objects.get(username= user.username)
        profile.save()
        return redirect(self.success_url)

addUser.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="." method="post">
            {% csrf_token %}
            {{ form }}     
            <button type="submit">Add</button>
        </form>
     </body>
</html>

urls.py

from django.conf.urls import url, include
from appName.views import *
urlpatterns = [
    url(r'^add-user/
, AddUser.as_view(), name='add-user'),
]
葬花如无物 2024-07-11 22:28:00

下面是扩展用户的另一种方法。
我觉得它比上面两种方法更清晰、简单、可读。

http://scottbarnham.com/ blog/2008/08/21/extending-the-django-user-model-with-inheritance/

使用上述方法:

  1. 您不需要使用
    user.get_profile().newattribute 访问附加信息
    与用户相关,
  2. 您可以直接访问
    额外的新属性通过
    用户.新属性

The below one is another approach to extend an User.
I feel it is more clear,easy,readable then above two approaches.

http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/

Using above approach:

  1. you don't need to use
    user.get_profile().newattribute to access the additional information
    related to the user
  2. you can just directly access
    additional new attributes via
    user.newattribute
清风不识月 2024-07-11 22:28:00

有一个官方建议存储有关的其他信息用户
Django Book还在配置文件部分讨论了这个问题。

There is an official recommendation on storing additional information about users.
The Django Book also discusses this problem in section Profiles.

征﹌骨岁月お 2024-07-11 22:28:00

像专业人士一样扩展 Django 用户模型 (UserProfile)

我发现这非常有用:链接

摘录:

from django.contrib.auth.models import User

class Employee(models.Model):
    user = models.OneToOneField(User)
    department = models.CharField(max_length=100)

>>> u = User.objects.get(username='fsmith')
>>> freds_department = u.employee.department

Extending Django User Model (UserProfile) like a Pro

I've found this very useful: link

An extract:

from django.contrib.auth.models import User

class Employee(models.Model):
    user = models.OneToOneField(User)
    department = models.CharField(max_length=100)

>>> u = User.objects.get(username='fsmith')
>>> freds_department = u.employee.department
卖梦商人 2024-07-11 22:28:00

在 Django 3.0+ 版本中这非常简单(如果您不在项目中):

models.py

from django.db import models
from django.contrib.auth.models import AbstractUser

class CustomUser(AbstractUser):
    extra_field=models.CharField(max_length=40)

中 在 settings.py

首先,注册您的新应用,然后注册AUTH_PASSWORD_VALIDATORS
最后

AUTH_USER_MODEL ='users.CustomUser'

,在管理员中注册您的模型,运行 makemigrations 并迁移,即可成功完成。

官方文档: https://docs .djangoproject.com/en/3.2/topics/auth/customizing/#substituting-a-custom-user-model

It's very easy in Django version 3.0+ (If you are NOT in the middle of a project):

In models.py

from django.db import models
from django.contrib.auth.models import AbstractUser

class CustomUser(AbstractUser):
    extra_field=models.CharField(max_length=40)

In settings.py

First, register your new app and then below AUTH_PASSWORD_VALIDATORS
add

AUTH_USER_MODEL ='users.CustomUser'

Finally, register your model in the admin, run makemigrations and migrate, and it will be completed successfully.

Official doc: https://docs.djangoproject.com/en/3.2/topics/auth/customizing/#substituting-a-custom-user-model

你好,陌生人 2024-07-11 22:28:00

在这里我试图解释如何使用额外的字段扩展 Django 的默认用户模型
非常简单,只要做就可以了。

Django 允许使用 AbstractUser 扩展默认用户模型

注意:- 首先创建一个要添加到用户模型中的额外字段模型,然后运行命令 python manage。 py makemigrationspython manage.py migrate

首次运行 ---> python manage.py makemigrations 然后

第二次运行 python manage.py migrate

步骤:- 创建一个模型,其中包含要添加到 Django 默认用户模型中的额外字段(在我的例子中)我创建了 CustomUser

model.py

from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.


class CustomUser(AbstractUser):
    mobile_no = models.IntegerField(blank=True,null=True)
    date_of_birth = models.DateField(blank=True,null=True)

在 settings.py 中添加您在我的案例中创建的模型名称 CustomUser 是注册的用户模型。 setttings.py 使其成为默认用户模型,

#settings.py

AUTH_USER_MODEL = 'myapp.CustomUser'

最后在 admin.py 中注册 CustomUser 模型
#admin.py

@admin.register(CustomUser)
class CustomUserAdmin(admin.ModelAdmin):
    list_display = ("username","first_name","last_name","email","date_of_birth", "mobile_no")

然后运行命令 python manage.py makemigrations

然后 python manage.py migrate

然后 python manage.py createsuperuser

现在你可以看到你的模型 默认用户模型扩展为 (mobile_no ,date_of_birth)

在此处输入图像描述

Here I tried to explain how to extend Django's Default user model with extra fields
It's very simple just do it.

Django allows extending the default user model with AbstractUser

Note:- first create an extra field model which you want to add in user model then run the command python manage.py makemigrations and python manage.py migrate

first run ---> python manage.py makemigrations then

second run python manage.py migrate

Step:- create a model with extra fields which you want to add in Django default user model (in my case I created CustomUser

model.py

from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.


class CustomUser(AbstractUser):
    mobile_no = models.IntegerField(blank=True,null=True)
    date_of_birth = models.DateField(blank=True,null=True)

add in settings.py name of your model which you created in my case CustomUser is the user model. registred in setttings.py to make it the default user model,

#settings.py

AUTH_USER_MODEL = 'myapp.CustomUser'

finally registred CustomUser model in admin.py
#admin.py

@admin.register(CustomUser)
class CustomUserAdmin(admin.ModelAdmin):
    list_display = ("username","first_name","last_name","email","date_of_birth", "mobile_no")

then run command python manage.py makemigrations

then python manage.py migrate

then python manage.py createsuperuser

now you can see your model Default User model extended with (mobile_no ,date_of_birth)

enter image description here

墨小沫ゞ 2024-07-11 22:28:00

Django 1.5 中的新增功能,现在您可以创建自己的自定义用户模型(在上述情况下这似乎是一件好事)。 请参阅 '在 Django 中自定义身份验证'

可能是 1.5 版本中最酷的新功能。

New in Django 1.5, now you can create your own Custom User Model (which seems to be good thing to do in above case). Refer to 'Customizing authentication in Django'

Probably the coolest new feature on 1.5 release.

救赎№ 2024-07-11 22:28:00

已经太晚了,但我的答案是针对那些使用最新版本的 Django 寻找解决方案的人。

models.py

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver


class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    extra_Field_1 = models.CharField(max_length=25, blank=True)
    extra_Field_2 = models.CharField(max_length=25, blank=True)


@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()

您可以在如下模板中使用它:

<h2>{{ user.get_full_name }}</h2>
<ul>
  <li>Username: {{ user.username }}</li>
  <li>Location: {{ user.profile.extra_Field_1 }}</li>
  <li>Birth Date: {{ user.profile.extra_Field_2 }}</li>
</ul>

以及在 views.py 中使用它,如下所示:

def update_profile(request, user_id):
    user = User.objects.get(pk=user_id)
    user.profile.extra_Field_1 = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit...'
    user.save()

It's too late, but my answer is for those who search for a solution with a recent version of Django.

models.py:

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver


class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    extra_Field_1 = models.CharField(max_length=25, blank=True)
    extra_Field_2 = models.CharField(max_length=25, blank=True)


@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.profile.save()

you can use it in templates like this:

<h2>{{ user.get_full_name }}</h2>
<ul>
  <li>Username: {{ user.username }}</li>
  <li>Location: {{ user.profile.extra_Field_1 }}</li>
  <li>Birth Date: {{ user.profile.extra_Field_2 }}</li>
</ul>

and in views.py like this:

def update_profile(request, user_id):
    user = User.objects.get(pk=user_id)
    user.profile.extra_Field_1 = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit...'
    user.save()
楠木可依 2024-07-11 22:28:00

目前从 Django 2.2 开始,开始新项目时推荐的方法是创建一个继承自 AbstractUser 的自定义用户模型,然后将 AUTH_USER_MODEL 指向该模型。

来源: https://docs.djangoproject.com/en/2.2/topics/auth/customizing/#using-a-custom-user-model-when-starting-a-project

Currently as of Django 2.2, the recommended way when starting a new project is to create a custom user model that inherits from AbstractUser, then point AUTH_USER_MODEL to the model.

Source: https://docs.djangoproject.com/en/2.2/topics/auth/customizing/#using-a-custom-user-model-when-starting-a-project

习惯那些不曾习惯的习惯 2024-07-11 22:28:00

简单有效的方法是
模型.py

from django.contrib.auth.models import User
class CustomUser(User):
     profile_pic = models.ImageField(upload_to='...')
     other_field = models.CharField()

Simple and effective approach is
models.py

from django.contrib.auth.models import User
class CustomUser(User):
     profile_pic = models.ImageField(upload_to='...')
     other_field = models.CharField()
朮生 2024-07-11 22:28:00

试试这个:

创建一个名为 Profile 的模型,并使用 OneToOneField 引用用户,并提供 lated_name 选项。

models.py

from django.db import models
from django.contrib.auth.models import *
from django.dispatch import receiver
from django.db.models.signals import post_save

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='user_profile')

    def __str__(self):
        return self.user.username

@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    try:
        if created:
            Profile.objects.create(user=instance).save()
    except Exception as err:
        print('Error creating user profile!')

现在,要使用 User 对象直接访问配置文件,您可以使用 lated_name

views.py

from django.http import HttpResponse

def home(request):
    profile = f'profile of {request.user.user_profile}'
    return HttpResponse(profile)

Try this:

Create a model called Profile and reference the user with a OneToOneField and provide an option of related_name.

models.py

from django.db import models
from django.contrib.auth.models import *
from django.dispatch import receiver
from django.db.models.signals import post_save

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='user_profile')

    def __str__(self):
        return self.user.username

@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    try:
        if created:
            Profile.objects.create(user=instance).save()
    except Exception as err:
        print('Error creating user profile!')

Now to directly access the profile using a User object you can use the related_name.

views.py

from django.http import HttpResponse

def home(request):
    profile = f'profile of {request.user.user_profile}'
    return HttpResponse(profile)
顾忌 2024-07-11 22:28:00

我建议 替换自定义用户模型扩展现有的用户模型

替换自定义用户模型

  • 可以添加额外的字段。
  • 可以删除默认字段。
  • 可以将默认的用户名密码身份验证更改为电子邮件密码身份验证。
  • 必须是第一次迁移到数据库,否则会出现错误。

*您可以查看我的回答,解释如何设置电子邮件password 身份验证 AbstractUserAbstractBaseUserPermissionsMixin,你可以看到我的答案我的回答解释了AbstractUser<之间的区别/code> 和 AbstractBaseUser

扩展现有的用户模型

  • 可以添加额外的字段。
  • 无法删除默认字段。
  • 无法将用户名密码身份验证更改为电子邮件密码身份验证。
  • 不需要是第一次迁移到数据库。

*您可以看到我的回答解释了如何扩展 用户model 添加额外字段 OneToOneField()

I recommend Substituting a custom User model which is more customizable than Extending the existing User model.

Substituting a custom User model:

  • can add extra fields.
  • can remove default fields.
  • can change default username and password authentication to email and password authentication.
  • must be the 1st migration to database otherwise there is error.

*You can see my answer explaining how to set up email and password authentication with AbstractUser or AbstractBaseUser and PermissionsMixin and you can see my answer and my answer explaining the difference between AbstractUser and AbstractBaseUser.

Extending the existing User model:

  • can add extra fields.
  • cannot remove default fields.
  • cannot change username and password authentication to email and password authentication.
  • doesn't need to be the 1st migration to database.

*You can see my answer explaining how to extend User model to add extra fields with OneToOneField().

无语# 2024-07-11 22:28:00

这就是我所做的,并且在我看来这是最简单的方法。 为您的新定制模型定义对象管理器,然后定义您的模型。

from django.db import models
from django.contrib.auth.models import PermissionsMixin, AbstractBaseUser, BaseUserManager

class User_manager(BaseUserManager):
    def create_user(self, username, email, gender, nickname, password):
        email = self.normalize_email(email)
        user = self.model(username=username, email=email, gender=gender, nickname=nickname)
        user.set_password(password)
        user.save(using=self.db)
        return user

    def create_superuser(self, username, email, gender, password, nickname=None):
        user = self.create_user(username=username, email=email, gender=gender, nickname=nickname, password=password)
        user.is_superuser = True
        user.is_staff = True
        user.save()
        return user



  class User(PermissionsMixin, AbstractBaseUser):
    username = models.CharField(max_length=32, unique=True, )
    email = models.EmailField(max_length=32)
    gender_choices = [("M", "Male"), ("F", "Female"), ("O", "Others")]
    gender = models.CharField(choices=gender_choices, default="M", max_length=1)
    nickname = models.CharField(max_length=32, blank=True, null=True)

    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    REQUIRED_FIELDS = ["email", "gender"]
    USERNAME_FIELD = "username"
    objects = User_manager()

    def __str__(self):
        return self.username

不要忘记在您的 settings.py 中添加这行代码:

AUTH_USER_MODEL = 'YourApp.User'

这就是我所做的,它总是有效的。

This is what i do and it's in my opinion simplest way to do this. define an object manager for your new customized model then define your model.

from django.db import models
from django.contrib.auth.models import PermissionsMixin, AbstractBaseUser, BaseUserManager

class User_manager(BaseUserManager):
    def create_user(self, username, email, gender, nickname, password):
        email = self.normalize_email(email)
        user = self.model(username=username, email=email, gender=gender, nickname=nickname)
        user.set_password(password)
        user.save(using=self.db)
        return user

    def create_superuser(self, username, email, gender, password, nickname=None):
        user = self.create_user(username=username, email=email, gender=gender, nickname=nickname, password=password)
        user.is_superuser = True
        user.is_staff = True
        user.save()
        return user



  class User(PermissionsMixin, AbstractBaseUser):
    username = models.CharField(max_length=32, unique=True, )
    email = models.EmailField(max_length=32)
    gender_choices = [("M", "Male"), ("F", "Female"), ("O", "Others")]
    gender = models.CharField(choices=gender_choices, default="M", max_length=1)
    nickname = models.CharField(max_length=32, blank=True, null=True)

    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    REQUIRED_FIELDS = ["email", "gender"]
    USERNAME_FIELD = "username"
    objects = User_manager()

    def __str__(self):
        return self.username

Dont forget to add this line of code in your settings.py:

AUTH_USER_MODEL = 'YourApp.User'

This is what i do and it always works.

原野 2024-07-11 22:28:00

最不痛苦且确实是 Django 推荐的方法是通过 OneToOneField(User) 属性。

扩展现有的用户模型

如果您希望存储与用户相关的信息,您可以使用与包含附加信息字段的模型的一对一关系。 这种一对一的模型通常称为配置文件模型,因为它可能存储有关站点用户的非身份验证相关信息。

也就是说,扩展 django.contrib.auth.models.User 并取代它也可以...

替换自定义用户模型

某些类型的项目可能有身份验证要求,而 Django 的内置 User 模型并不总是适合。 例如,在某些网站上,使用电子邮件地址而不是用户名作为识别令牌更有意义。

[编者:随后出现两条警告和一条通知,并提到这是相当激烈。]

我绝对不会更改实际的 User 类在您的 Django 源代码树中和/或复制并更改 auth 模块。

The least painful and indeed Django-recommended way of doing this is through a OneToOneField(User) property.

Extending the existing User model

If you wish to store information related to User, you can use a one-to-one relationship to a model containing the fields for additional information. This one-to-one model is often called a profile model, as it might store non-auth related information about a site user.

That said, extending django.contrib.auth.models.User and supplanting it also works...

Substituting a custom User model

Some kinds of projects may have authentication requirements for which Django’s built-in User model is not always appropriate. For instance, on some sites it makes more sense to use an email address as your identification token instead of a username.

[Ed: Two warnings and a notification follow, mentioning that this is pretty drastic.]

I would definitely stay away from changing the actual User class in your Django source tree and/or copying and altering the auth module.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文