前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Django实践:自定义用户系统

Django实践:自定义用户系统

作者头像
用户3004328
发布2018-09-06 16:46:32
8990
发布2018-09-06 16:46:32
举报
文章被收录于专栏:增长技术增长技术

扩展Django的用户系统有几个方法:

  • 1.在自定义Model中使用OneToOneField的方式来扩展,实现一个User Profile。 这种方式在1.5之前是推荐的,在User也有一个默认的get_profile方法来获取这个profile。 这种方式的好处是1.5以前的版本默认支持,并且对Django的影响最小,坏处主要是获取资料的时候需要一次join表。 示例代码如下: class UserProfile(models.Model): user = models.OneToOneField('auth.User') bio = models.TextField()
  • 2.从Django的User派生或者重写,这样要比较小心地满足Django一些耦合的地方,才能利用起Django的用户认证 和管理。这种方式不推荐,维护起来很麻烦,也容易产生冲突。
  • 3.在Django1.5开始加强了用户自定义的功能,从AbstractBaseUser, PermissionsMixin开始派生出一个自定用户Model, 并且实现自定义的BaseUserManager就能够使用Django来创建用户。为了在Django管理界面管理自定义的用户,还需要实现自定义的UserAdmin。 下面是例子: 常用的做法应该是放到单独的用户app譬如user或者account下面。

在user/models.py放以下代码:

代码语言:javascript
复制
  from django.db import models
  from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin

  class MyUserManager(BaseUserManager):
      def create_user(self, nick_name, email, password, **extra_fields):
      if not email:
        raise ValueError('Users must have an email address')

      user = self.model(
          nick_name=nick_name,
          email=MyUserManager.normalize_email(email),
          is_staff=False,
          is_active=True,
          is_superuser=False,
          **extra_fields
      )
      user.set_password(password)
      user.save(using=self._db)
      return user

      def create_superuser(self, nick_name, email, password, **extra_fields):
          user = self.create_user(nick_name,
              email,
              password,
              **extra_fields
          )
          user.is_staff=True
          user.is_active=True
          user.is_superuser = True
          user.save(using=self._db)
          return user

  # 在settings里面指定这个User类为AUTH_USER_MODEL
  class User(AbstractBaseUser, PermissionsMixin):
      nick_name = models.CharField(max_length=100, unique=True, db_index=True)
      pwd = models.CharField(max_length=128)
      mobilebind = models.IntegerField(default=0)
      phone = models.CharField(max_length=20)
      say = models.CharField(max_length=255)
      email = models.EmailField(verbose_name='email address',max_length=254)

      is_staff = models.BooleanField('staff status', default=False,
          help_text='flag for log into admin site.')
      is_active = models.BooleanField('active', default=True)

      USERNAME_FIELD = 'nick_name'
      REQUIRED_FIELDS = ['email']
      objects = MyUserManager()     # 在这里关联自定义的UserManager

      def get_full_name(self):
          return self.nick_name

      def get_short_name(self):
          return self.nick_name

      def __unicode__(self):
          return self.nick_name
      #def is_authenticated(self):  
      #    return True  

      '''
      # 这个函数可以实现自定义的用户密码检验,除非你想跳过Django的才实现。
      def check_password(self, password):  
          if self.hashed_password(password) == self.pwd:  
              return True
          print 'debug: password(%s), hashed %s, self.pwd %s' % (password, self.hashed_password(password), self.pwd)
          return False
      '''

      '''
      # 这里可以实现自己的密码管理
      def set_password(self, raw_password):
          print 'set_password called'
          self.pwd = self.my_hashed_pwd(raw_password)
          super(User, self).set_password(raw_password)
      '''
      # 如果要自定义表名的话
      class Meta:  
          db_table = "myuser"

  # 其他要用到user的地方直接用这个自定义的user就好了
  class FriendRelation(models.Model):
      user = models.ForeignKey(User)
      friend = models.IntegerField()

然后在project的settings.py里面加入:

代码语言:javascript
复制
  AUTH_USER_MODEL = 'user.User'

接着在user/admin.py(没有就创建)中加入以下代码:

代码语言:javascript
复制
  from django import forms
  from django.contrib import admin
  from django.contrib.auth.models import Group
  from django.contrib.auth.admin import UserAdmin
  from django.contrib.auth.forms import ReadOnlyPasswordHashField
  from user.models import User  # 这里改成对应的包

  class UserCreationForm(forms.ModelForm):
      """A form for creating new users. Includes all the required
      fields, plus a repeated password."""
      password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
      password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

      class Meta:
          model = User
          fields = ('nick_name', 'pwd', 'email', 'mobilebind', 'say')  # 改成想要的字段

      def clean_password2(self):
          # Check that the two password entries match
          password1 = self.cleaned_data.get("password1")
          password2 = self.cleaned_data.get("password2")
          if password1 and password2 and password1 != password2:
              raise forms.ValidationError("Passwords don't match")
          return password2

      def save(self, commit=True):
          # Save the provided password in hashed format
          user = super(UserCreationForm, self).save(commit=False)
          user.set_password(self.cleaned_data["password1"])
          if commit:
              user.save()
          return user


  class UserChangeForm(forms.ModelForm):
      """A form for updating users. Includes all the fields on
      the user, but replaces the password field with admin's
      password hash display field.
      """
      password = ReadOnlyPasswordHashField()

      class Meta:
          model = User

      def clean_password(self):
          # Regardless of what the user provides, return the initial value.
          # This is done here, rather than on the field, because the
          # field does not have access to the initial value
          return self.initial["password"]


  class MyUserAdmin(UserAdmin):
      # The forms to add and change user instances
      form = UserChangeForm
      add_form = UserCreationForm

      # The fields to be used in displaying the User model.
      # These override the definitions on the base UserAdmin
      # that reference specific fields on auth.User.
      list_display = ('nick_name', 'email', 'is_superuser')
      list_filter = ('is_superuser',)
      fieldsets = (
          (None, {'fields': ('nick_name', 'email', 'password')}),
          ('Personal info', {'fields': ('pwd',)}),
          ('Permissions', {'fields': ('is_superuser',)}),
          #('Important dates', {'fields': ('last_login',)}),
      )
      add_fieldsets = (
          (None, {
              'classes': ('wide',),
              'fields': ('nick_name', 'pwd', 'email', 'password1', 'password2')}
          ),
      )
      search_fields = ('nick_name', 'email',)
      ordering = ('nick_name', 'email',)
      filter_horizontal = ()

  # Now register the new UserAdmin...
  admin.site.register(User, MyUserAdmin)
  # ... and, since we're not using Django's builtin permissions,
  # unregister the Group model from admin.
  admin.site.unregister(Group)

通过以上步骤就已经完成了一个自定义的用户模型,需要重新使用./manager.py sync产生数据库。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2014-07-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 扩展Django的用户系统有几个方法:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档