Django如何继承AbstractUser扩展字段

使用django实现注册登录的话,注册登录都有现成的代码,主要是自带的User字段只有(email,username,password),所以需要扩展User,来增加自己需要的字段

AbstractUser扩展模型User:如果模型User内置的方法符合开发需求,在不改变这些函数方法的情况下,添加模型User的额外字段,可通过AbstractUser方式实现。使用AbstractUser定义的模型会替换原有模型User。

代码如下:

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、扩展user表后,要在settings.py 添加

AUTH_USER_MODEL = \’appname.扩展user的class name\’

2、认证后台要在settings添加,尤其记得加逗号,否则报错

认证后台不加的报错

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不能为空\",})

迁移数据库

python manage.py makemigrations
python manage.py migrate

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、登陆的时候用自带的认证模块总是报none

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

查看源码发现是check_password的方法是用hash进行校验,之前注册的password写法是

user.password=password

这种写法是明文入库,需要更改密码的入库写法

user.set_password(password)

补充

一个快速拿到User表的方法,特别在扩展User表时,你在settings.py配置的User。

from django.contrib.auth import get_user_model
User = get_user_model()

别在其他视图或者模型里导入你扩展的MyUser model。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容