Django如何继承AbstractUser扩展字段


Posted in Python onNovember 27, 2020

使用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。

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

Python 相关文章推荐
Python version 2.7 required, which was not found in the registry
Aug 26 Python
Python实现截屏的函数
Jul 25 Python
Python 逐行分割大txt文件的方法
Oct 10 Python
python3.6连接MySQL和表的创建与删除实例代码
Dec 28 Python
Python3.0中普通方法、类方法和静态方法的比较
May 03 Python
获取Pytorch中间某一层权重或者特征的例子
Aug 17 Python
python使用matplotlib绘制雷达图
Oct 18 Python
pandas中遍历dataframe的每一个元素的实现
Oct 23 Python
python实现操作文件(文件夹)
Oct 31 Python
python3的UnicodeDecodeError解决方法
Dec 20 Python
python如何实现单链表的反转
Feb 10 Python
Python 随机按键模拟2小时
Dec 30 Python
如何使用 Flask 做一个评论系统
Nov 27 #Python
python+openCV对视频进行截取的实现
Nov 27 #Python
Python环境配置实现pip加速过程解析
Nov 27 #Python
python实现学生信息管理系统(精简版)
Nov 27 #Python
基于Python采集爬取微信公众号历史数据
Nov 27 #Python
Django中日期时间型字段进行年月日时分秒分组统计
Nov 27 #Python
Python基于execjs运行js过程解析
Nov 27 #Python
You might like
PHP 中的批处理的实现
2007/06/14 PHP
优化PHP代码的53条建议
2008/03/27 PHP
解析Extjs与php数据交互(增删查改)
2013/06/25 PHP
ThinkPHP整合百度Ueditor图文教程
2014/10/21 PHP
php采用file_get_contents代替使用curl实例
2014/11/07 PHP
使用JavaScript创建新样式表和新样式规则
2016/06/14 PHP
php中的单引号、双引号和转义字符详解
2017/02/16 PHP
jQuery操作input type=radio的实现代码
2012/06/14 Javascript
JavaScript:Div层拖动效果实例代码
2013/08/06 Javascript
判断文件是否正在被使用的JS代码
2013/12/21 Javascript
JavaScript操作class和style样式代码详解
2016/02/13 Javascript
jQuery UI Bootstrap是什么?
2016/06/17 Javascript
Node.js使用NodeMailer发送邮件实例代码
2017/03/06 Javascript
js案例之鼠标跟随jquery版(实例讲解)
2017/07/21 jQuery
利用vue + koa2 + mockjs模拟数据的方法教程
2017/11/22 Javascript
js cavans实现静态滚动弹幕
2020/05/21 Javascript
在Python中操作字典之fromkeys()方法的使用
2015/05/21 Python
Python实现多线程抓取网页功能实例详解
2017/06/08 Python
使用python 和 lint 删除项目无用资源的方法
2017/12/20 Python
Python读取Excel表格,并同时画折线图和柱状图的方法
2018/10/14 Python
python mac下安装虚拟环境的图文教程
2019/04/12 Python
浅谈sklearn中predict与predict_proba区别
2020/06/28 Python
PyCharm2019 安装和配置教程详解附激活码
2020/07/31 Python
使用py-spy解决scrapy卡死的问题方法
2020/09/29 Python
最新PyCharm从安装到PyCharm永久激活再到PyCharm官方中文汉化详细教程
2020/11/17 Python
家得宝墨西哥官网:The Home Depot墨西哥
2019/11/18 全球购物
如何利用cmp命令比较文件
2016/04/11 面试题
考试违纪检讨书
2014/02/02 职场文书
机关工会开展学习雷锋活动总结
2014/03/01 职场文书
学校领导班子成员查摆问题及整改措施
2014/10/28 职场文书
入党后的感想
2015/08/10 职场文书
初三语文教学反思
2016/03/03 职场文书
公文写作:工伤事故分析报告怎么写?
2019/11/05 职场文书
少年的你:世界上没有如果,要在第一次就勇敢的反抗
2019/11/20 职场文书
自己搭建resnet18网络并加载torchvision自带权重的操作
2021/05/13 Python
JS实现简单的九宫格抽奖
2022/06/28 Javascript