環境

Pythonの3.5.1

ジャンゴ1.9.1

序文

今日では、Djangoの書き込みWebプラットフォーム、Djangoの認証セッションは、車輪があるので、より良い提供しており、私たちは自分自身が構築する必要はありません来て最初に考えたと。

メソッドのDjangoのユーザーの拡張:

書き換えユーザーは、管理者に新しいユーザーを登録しますが、また、認定を書き換えます

第二に、継承されたユーザーは、拡大(AUTH_USER_MODELの設定を設定することを忘れないでください

AUTH_USER_MODEL = "myapp.NewUser"
 

2.1クラスはAbstractUserを継承します

あなたはジャンゴに満足しているUserモデルが付属しており、追加のフィールドを追加したいと考えていた場合、あなたはAbstractUserクラスを拡張することができます(この論文では、このメソッドを実装することです)

新しいDjangoのUserクラスは、電子メールをサポートして、あなたはまた、ユーザーのログインとして電子メールを使用することができます

2.2クラスはAbstractBaseUserを継承します

AbstractBaseUserは3つだけのフィールドが含まれます。パスワード、last_loginをしてis_activeこれは、彼らが必要とする独自の高度にカスタマイズされたものです。

model.py

# class UserManager(BaseUserManager):
#     # def create_user(self, email, username, mobile, password=None):
#     def create_user(self, email, username, mobile, password=None, **kwargs):
#         """通过邮箱,密码,手机号创建用户"""
# if not email: # raise ValueError(u'用户必须要有邮箱') # # user = self.model( # email = self.normalize_email(email), # username = username, # mobile = mobile, # ) # # user.set_password(password) # if kwargs: # if kwargs.get('qq', None): user.qq = kwargs['qq'] #qq号 # if kwargs.get('is_active', None): user.is_active = kwargs['is_active'] #是否激活 # if kwargs.get('wechat', None): user.wechat = kwargs['wechat'] #微信号 # if kwargs.get('refuserid', None): user.refuserid = kwargs['refuserid'] #推荐人ID # if kwargs.get('vevideo', None): user.vevideo = kwargs['vevideo'] #视频认证 # if kwargs.get('identicard', None): user.identicard = kwargs['identicard'] #×××认证 # if kwargs.get('type', None): user.type = kwargs['type'] # user.save(using=self._db) # return user # # def create_superuser(self,email, username, password,mobile): # user = self.create_user(email, # username=username, # password=password, # mobile = mobile, # ) # user.is_admin = True # user.save(using=self.db) # return user # # class User(AbstractBaseUser, PermissionsMixin): # """扩展User""" # email = models.EmailField(verbose_name='Email', max_length=255, unique=True, db_index=True) # username = models.CharField(max_length=50) # qq = models.CharField(max_length=16) # mobile = models.CharField(max_length=11) # wechat = models.CharField(max_length=100) # refuserid = models.CharField(max_length=20) # vevideo = models.BooleanField(default=False) # identicard = models.BooleanField(default=False) # created_at = models.DateTimeField(auto_now_add=True) # type = models.CharField(u'用户类型', default='0', max_length=1) # # is_active = models.BooleanField(default=True) # is_admin = models.BooleanField(default=False) # # objects = UserManager() # # USERNAME_FIELD = 'email' # REQUIRED_FIELDS = ['mobile'] # # 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 # # #On python 2: def __unicode__(self): # def __str__(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 #
 

admin.py

# class UserCreationForm(forms.ModelForm):
#     password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
#     password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
#
# class Meta: # model = MyUser # fields = ('email', 'mobile') # # 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): # password = ReadOnlyPasswordHashField() # # class Meta: # model = MyUser # fields = ('email', 'password', 'mobile', 'is_active', 'is_admin') # # def clean_password(self): # return self.initial['password'] # # class UserAdmin(BaseUserAdmin): # form = UserChangeForm # add_form = UserCreationForm # list_display = ('email', 'mobile','is_admin') # list_filter = ('is_admin',) # fieldsets = ( # (None, {'fields': ('email', 'password')}), # ('Personal info', {'fields': ('mobile',)}), # ('Permissions', {'fields': ('is_admin',)}), # ) # add_fieldsets = ( # (None, { # 'classes': ('wide',), # 'fields' :('email','mobile', 'password1', 'password2')} # ), # ) # search_fields = ('email',) # ordering = ('email',) # filter_horizontal = () # # admin.site.register(MyUser,UserAdmin) # admin.site.unregister(Group)
 

拡大するが、最初からこのようなアプローチのdjango1.6を放棄するために3つ、プロファイルの方法

第四に、オンラインの方法は、新しいテーブルなしで、ソースコードを変更しないでください、見つけるため、拡張されたユーザー

from django.db import models  from django.contrib.auth.models import User from django.contrib.auth.admin import UserAdmin import datetime class ProfileBase(type): def __new__(cls, name, bases, attrs): #构造器,(名字,基类,类属性) module = attrs.pop('__module__') parents = [b for b in bases if isinstance(b, ProfileBase)] if parents: fields = [] for obj_name, obj in attrs.items(): if isinstance(obj, models.Field): fields.append(obj_name) User.add_to_class(obj_name, obj) ####最重要的步骤 UserAdmin.fieldsets = list(UserAdmin.fieldsets) UserAdmin.fieldsets.append((name, {'fields': fields})) return super(ProfileBase, cls).__new__(cls, name, bases, attrs) class ProfileUser(object): __metaclass__ = ProfileBase class ExtraInfo(ProfileUser): phone_number= models.CharField(max_length = 20, verbose_name=u'电话号码')
 

 

このコードを少し説明:ProfileBaseは、カスタムメタクラスから継承しているtypes.ClassType基底クラスProfileUserれ、そのメタクラスはProfileBaseですが、私たちが本当にextraInfoはカスタムフィールドタイプ、理由基底クラスProfileUserそしてextraInfoは別に、参照ProfileUserを容易にするために他の場所で、カスタム拡張用。それは元を実行するときにサブクラスProfileUserクラスとメタクラスProfileUserクラスの定義の中で通訳を見たときだけで、入れメタクラスは、サブクラス定義ProfileUserで、ProfileBaseあるとextrainfoのでProfileBaseは、ありますクラスは、新しいコードをProfileBase、そしてクラスで定義されている(基底クラスの名前、クラス属性が)ここに新しい、名前にパラメータとして渡されたが、クラスとextrainfoの名前であることで、媒体が新しく追加されたフィールドが含まれていますATTRS User.add_to_class新しいフィールドは、管理者に表示に追加することができるようにするためには、ユーザーに追加されるUserAdmin.fieldsets途中、それがリストに表示されるように、あなたは、もちろん、あなたもist_displayに追加することができ、バックグラウンドでこのフィールドを編集することができます。

あなたは他のアプリでもカテゴリー別にすべてのサブクラスProfileUser限り、フィールドやメソッドにおけるユーザーモデルに追加して、他のすべての作業を定義する宣言構文を使用したい持っている場合は、完了するのに役立ちメタクラスがあります。これはまた、すべてのDjangoのモデルの内部の仕組みである、あなたが任意のモデルを拡張するために、このメソッドを使用することができます。

転載元:http://www.opscoder.info/extend_user.html

需要

ログインユーザーフィールド主のみ(メール、ユーザ名、パスワード)が付属しています既製のコードを持って登録し、それがユーザーを拡大する必要がある、我々はフィールドを増やす必要があります

 

コードは以下の通りであります:

 

model.py

#coding:utf8
from django.db import models
from django.contrib.auth.models import AbstractUser from django.utils.encoding import python_2_unicode_compatible # Create your models here. @python_2_unicode_compatible """是django内置的兼容python2和python3的unicode语法的一个装饰器 只是针对 __str__ 方法而用的,__str__方法是为了后台管理(admin)和django shell的显示,Meta类也是为后台显示服务的 """ class MyUser(AbstractUser): qq = models.CharField(u'qq号', max_length=16) weChat =models.CharField(u'微信账号', max_length=100) mobile =models.CharField(u'手机号', primary_key=True, max_length=11) identicard =models.BooleanField(u'×××认证', default=False) #默认是0,未认证, 1:×××认证, 2:视频认证 refuserid = models.CharField(u'推荐人ID', max_length=20) Level = models.CharField(u'用户等级', default='0', max_length=2) #默认是0,用户等级0-9 vevideo = models.BooleanField(u'视频认证', default=False) #默认是0,未认证。 1:已认证 Type =models.CharField(u'用户类型', default='0', max_length=1) #默认是0,未认证, 1:刷手 2:商家 def __str__(self): return self.username
 

 

settings.py

AUTH_USER_MODEL = 'appname.MyUser'
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
 

段ピット:

図1は、拡張されたユーザ・テーブルの後、settings.pyに追加します

AUTH_USER_MODEL = 'appname.扩展user的class name'
 

、特にコンマを覚えて、それ以外の場合はエラーを追加するためにバックグラウンドで2、認証設定

与えられずに背景を認定

Django-AttributeError 'User' object has no attribute 'backend'
 

エラーは、カンマを追加しませんでした

ImportError: a doesn't look like a module path
 

 

form.py

#coding:utf-8
from django import forms

#注册表单
class RegisterForm(forms.Form): username = forms.CharField(label='用户名',max_length=100) password = forms.CharField(label='密码',widget=forms.PasswordInput()) password2 = forms.CharField(label='确认密码',widget=forms.PasswordInput()) mobile = forms.CharField(label='手机号', max_length=11) email = forms.EmailField() qq = forms.CharField(label='QQ号', max_length=16) type = forms.ChoiceField(label='注册类型', choices=(('buyer','买家'),('saler','商家'))) def clean(self): if not self.is_valid(): raise forms.ValidationError('所有项都为必填项') elif self.cleaned_data['password2'] != self.cleaned_data['password']: raise forms.ValidationError('两次输入密码不一致') else: cleaned_data = super(RegisterForm, self).clean() return cleaned_data #登陆表单 class LoginForm(forms.Form): username = forms.CharField(label='用户名',widget=forms.TextInput(attrs={"placeholder": "用户名", "required": "required",}), max_length=50, error_messages={"required": "username不能为空",}) password = forms.CharField(label='密码',widget=forms.PasswordInput(attrs={"placeholder": "密码", "required": "required",}), max_length=20, error_messages={"required": "password不能为空",})
 

 

views.py

from django.shortcuts import render,render_to_response
from .models import MyUser from django.http import HttpResponse,HttpResponseRedirect from django.template import RequestContext import time from .myclass import form from django.template import RequestContext from django.contrib.auth import authenticate,login,logout #注册 def register(request): error = [] # if request.method == 'GET': # return render_to_response('register.html',{'uf':uf}) if request.method == 'POST': uf = form.RegisterForm(request.POST) if uf.is_valid(): username = uf.cleaned_data['username'] password = uf.cleaned_data['password'] password2 = uf.cleaned_data['password2'] qq = uf.cleaned_data['qq'] email = uf.cleaned_data['email'] mobile = uf.cleaned_data['mobile'] type = uf.cleaned_data['type'] if not MyUser.objects.all().filter(username=username): user = MyUser() user.username = username user.set_password(password) user.qq = qq user.email = email user.mobile = mobile user.type = type user.save() return render_to_response('member.html', {'username': username}) else: uf = form.RegisterForm() return render_to_response('register.html',{'uf':uf,'error':error}) #登陆 def do_login(request): if request.method =='POST': lf = form.LoginForm(request.POST) if lf.is_valid(): username = lf.cleaned_data['username'] password = lf.cleaned_data['password'] user = authenticate(username=username, password=password) #django自带auth验证用户名密码 if user is not None: #判断用户是否存在 if user.is_active: #判断用户是否激活 login(request,user) #用户信息验证成功后把登陆信息写入session return render_to_response("member.html", {'username':username}) else: return render_to_response('disable.html',{'username':username}) else: return HttpResponse("无效的用户名或者密码!!!") else: lf = form.LoginForm() return render_to_response('index.html',{'lf':lf}) #退出 def do_logout(request): logout(request) return HttpResponseRedirect('/')
 

 

段ピット:

1、内蔵の認証モジュールで着陸するときは、必ずどれも報告されていません

user = authenticate(username=username, password=password)
 

登録される前にcheck_passwordなアプローチであることが判明ビューソースはハッシュで確認することで、パスワードが書かれました

user.password=password
 

文言が明示保管され、我々はパスワード保存の文言を変更する必要があります

user.set_password(password)