Extending the User model with custom fields in Django
使用自定义字段扩展用户模型(与Django的身份验证应用程序捆绑在一起)的最佳方法是什么?我也可能想使用电子邮件作为用户名(用于身份验证)。
我已经看到了一些方法,但无法决定哪一种是最好的。
Django推荐的最不痛苦的方法是通过
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.
号
也就是说,扩展EDOCX1[1]并取代它也有效…
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.]
号
我绝对不会更改Django源代码树中的实际用户类和/或复制和更改auth模块。
注意:此答案已弃用。如果您使用的是django 1.7或更高版本,请参阅其他答案。
我就是这样做的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #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' |
这将在每次保存用户时创建一个用户配置文件(如果已创建)。然后你可以使用
1 | user.get_profile().whatever |
号
这是从医生那里得到的更多信息
http://docs.djangoproject.com/en/dev/topics/auth/存储有关用户的其他信息
更新:请注意,由于v1.5:https://docs.djangoproject.com/en/1.5/ref/settings/auth profile module,因此不推荐使用
好吧,从2008年以来已经过去了一段时间,现在是时候换个新答案了。自Django1.5以来,您将能够创建自定义用户类。实际上,在我写这个的时候,它已经合并到master中了,所以你可以试试看。
在文档中有一些关于它的信息,或者如果您想深入了解它,在这个提交中。
您所要做的就是将
对于那些懒于点击的人,下面是代码示例(取自文档):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | 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 |
由于django 1.5,您可以轻松地扩展用户模型并在数据库中保留一个表。
1 2 3 4 5 6 | 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")) |
。
还必须将其配置为设置文件中的当前用户类
1 2 | # supposing you put it in apps/profiles/models.py AUTH_USER_MODEL ="profiles.UserProfile" |
如果你想增加很多用户的偏好,OneTooneField选项可能是一个更好的选择。
开发第三方库的人员注意:如果您需要访问用户类,请记住,用户可以更改它。使用官方助手获得正确的课程
1 2 3 | from django.contrib.auth import get_user_model User = get_user_model() |
。
关于存储有关用户的附加信息,有一个官方建议。Django的书也在章节简介中讨论了这个问题。
下面是扩展用户的另一种方法。我觉得它比上述两种方法更清晰、更容易阅读。
http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/
使用上述方法:
每次使用django post save信号创建用户时,只需创建一个新条目即可扩展用户配置文件。
型号.py1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | from django.db.models.signals import * from __future__ import unicode_literals class userProfile(models.Model): userName = models.OneToOneField(User, related_name='profile') city = models.CharField(max_length=100, null=True) def __unicode__(self): # __str__ return unicode(self.userName) def create_user_profile(sender, instance, created, **kwargs): if created: userProfile.objects.create(userName=instance) post_save.connect(create_user_profile, sender=User) |
这将在创建新用户时自动创建员工实例。
如果希望扩展用户模型并希望在创建用户时添加更多信息,可以使用django betterforms(http://django betterforms.readthedocs.io/en/latest/multiform.html)。这将创建一个用户添加表单,其中包含在用户配置文件模型中定义的所有字段。
型号.py1 2 3 4 5 6 7 8 9 10 | from django.db.models.signals import * from __future__ import unicode_literals class userProfile(models.Model): userName = models.OneToOneField(User) city = models.CharField(max_length=100) def __unicode__(self): # __str__ return unicode(self.userName) |
。表格.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 = ('userName',) class addUserMultiForm(MultiModelForm): form_classes = { 'user':UserCreationForm, 'profile':profileForm, } |
视图.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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 ="addUser.html" success_url = '/your url after user created' def form_valid(self, form): user = form['user'].save() profile = form['profile'].save(commit=False) profile.userName = User.objects.get(username= user.username) profile.save() return redirect(self.success_url) |
。添加用户.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> Title </head> <body> <form action="." method="post"> {% csrf_token %} {{ form }} <button type="submit">Add</button> </form> </body> </html> |
号网址.py
1 2 3 4 5 | from django.conf.urls import url, include from appName.views import * urlpatterns = [ url(r'^add-user/$', addUser.as_view(), name='addDistributor'), ] |
号
像专业人员一样扩展django用户模型(userprofile)
我发现这个非常有用:链接
摘录:
从django.contrib.auth.models导入用户
1 2 3 4 5 6 | 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 |
。
Django1.5中的新功能,现在您可以创建自己的自定义用户模型(在上述情况下,这似乎是一件好事)。请参阅"在Django中自定义身份验证"
可能是1.5版本中最酷的新功能。
这就是我所做的,在我看来,这是最简单的方法。为新的自定义模型定义对象管理器,然后定义模型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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 |
号
不要忘记在您的
1 | AUTH_USER_MODEL = 'YourApp.User' |
号
这就是我所做的,它总是有效的。