社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Django

django(v1.5) 自定义用户基础

frikyskice • 12 年前 • 12024 次点击  
#这是v1.5中新增加的功能
#本文由frikyskice 根据官方Docs自行描述,请以原文档为准
#https://docs.djangoproject.com/en/dev/topics/auth/customizing/#substituting-a-custom-user-model
#本文目的给英文不好的筒子们一个参考,不代表其正确性
#frikyskice授权任何个人或组织直接传播本文,但不包括此情况(以本文进行非公益性质的商业盈利)


#本人不专业,拒绝回答技术问题,以免误人误己

通过定义AUTH_USER_MODEL 可对User模型进行自定义扩展 例如:

AUTH_USER_MODEL = 'myapp.MyUser'

扩展的app必须装入INSTALLED_APPS中

如果你已经定义AUTH_USER_MODEL,系统中原有的User模型不能直接使用

以下均以已经定义AUTH_USER_MODEL作为假设

get_user_model() 该函数用以返回正在使用的自定义的User模型(注意不是系统中自带的那个User) 使用方法: django.contrib.auth.get_user_model() ‘’‘ 对于原有的外键及多对多关系,你需要使用宏的模式进行处理,如下:

from django.conf import settings
from django.db import models
class Article(models.Model):
        author = models.ForeignKey(settings.AUTH_USER_MODEL)

’‘’

如何自定义你的User模型 自定义User模型需要满足以下基本条件

  1. 模型必须有一个主键,并且是integer模型(建议不要在此做花样,直接autoXXXX,你懂的)
  2. 模型必须能有一个字段进行唯一性区分(注意不能是1中的东西),什么字段都可以
  3. 提供特定的方式以便于程序可以找到这个User(非系统自带),长短两个名称的form(这句大约就是这个意思)#in a “short” and “long” form#

当然这里最简单的方式是直接继承 AbstractBaseUser ,这样上面3个你可以不用管, AbstractBaseUser 就相当于djangoV1.4里面的User,如果你继承 AbstractBaseUser ,需要做以下内容:(我写的好啰嗦…………)

USERNAME_FIELD

例如:

class MyUser(AbstractBaseUser):
        identifier = models.CharField(max_length=40, unique=True, db_index=True)
        ...
        USERNAME_FIELD = 'identifier'

这里注意 identifier 中的unique=True 必须显示的标明,对应上面3条中的二条(麻将?)

REQUIRED_FIELDS

例如:

class MyUser(AbstractBaseUser):
        ...
        date_of_birth = models.DateField()
         height = models.FloatField()
         ...
         REQUIRED_FIELDS = ['date_of_birth', 'height']

**#这里是一个list,告诉系统那些是必须填的字段**

is_active

AbstractBaseUser 中默认的初始化为True,自己看着办吧

后面就是两函数,对应三条,嗯,你懂得,返回个字符串就行,啥啥的没关系,自己看着办

get_full_name()  |   get_short_name()

以下为AbstractBaseUser的其他一些方法,同v1.4中的User,不用重载,重载你也不用看我写的了

class models.AbstractBaseUserget_username()
    is_anonymous()
    is_authenticated()
    set_password(raw_password)
    check_password(raw_password)
    set_unusable_password()
    has_usable_password()

这里提一下,创建用户模型的时候最好加上username和email两个字段,这样你可以直接使用django自带的UserManager,如果没有,自己写一个吧,基类为 BaseUserManager, 必须提供以下两个方法

def create_user(self, email, date_of_birth, password=None):
    # create user here
    ...

def create_superuser(self, email, date_of_birth, password):
    # create superuser here
    ...

BaseUserManager也提供其他方法,自己查文档,不浪费口水了,当然你可以根据需要自己定义

以下为如何扩展django自己的User模型 如果django自带的User能满足你的要求,你可以简单的继承 django.contrib.auth.models.AbstractUser,并加入自己需要增加的简单字段。 凡是User模型提供的功能,AbstractUser都默认提供。 如果User模型不能满足你的要求,你需要完全自己定义相应的描述,并提供相应的功能来达到你的要求(包括相应的Forms)。

UserCreationForm

依赖User模型,任何自定义的模型都必须重载

UserChangeForm

依赖User模型,任何自定义的模型都必须重载

AuthenticationForm

与AbstractBaseUser的子类协同工作,与子类中的USERNAME_FIELD申明的字段相符,就是USERNAME_FIELD定义的啥,依据啥来验证用户

PasswordResetForm

原文举了个例子,自己去看吧,不过和密码相关的几个都不用重载

SetPasswordForm
PasswordChangeForm
AdminPasswordChangeForm

如何定义自定义User的admin功能 必须自己定义一个ModelAdmin的继承至django.contrib.auth.admin.UserAdmin的子类,这个很绕口,不过后面的例子一看就能明白,不做赘述。

由于本文用以扫盲,因此中间有几个话题略过

以下为Docs中的一个完整的例子: Filenames:models.py

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, email, date_of_birth, password):
        """
        Creates and saves a superuser with the given email, date of
        birth and password.
        """
        user = self.create_user(email,
            password=password,
            date_of_birth=date_of_birth
        )
        user.is_admin = True
        user.save(using=self._db)
        return user


class MyUser(AbstractBaseUser):
    email = models.EmailField(
        verbose_name='email address',
        max_length=


    
255,
        unique=True,
        db_index=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

Filenames:admin.py

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 customauth.models import MyUser


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 = MyUser
        fields = ('email', 'date_of_birth')

    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 = MyUser
        fields = 


    
['email', 'password', 'date_of_birth', 'is_active', 'is_admin']

    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 = ('email', 'date_of_birth', 'is_admin')
    list_filter = ('is_admin',)
    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Personal info', {'fields': ('date_of_birth',)}),
        ('Permissions', {'fields': ('is_admin',)}),
    )
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'date_of_birth', 'password1', 'password2')}
        ),
    )
    search_fields = ('email',)
    ordering = ('email',)
    filter_horizontal = ()

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

最后,你需要更改settings.py 文件

AUTH_USER_MODEL = 'customauth.MyUser'
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/133
 
12024 次点击  
文章 [ 1 ]  |  最新文章 12 年前
Py站长
Reply   •   1 楼
Py站长    12 年前

支持原创作者!