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 正则表达式 概述及常用字符
May 04 Python
Python中的hypot()方法使用简介
May 18 Python
Python之py2exe打包工具详解
Jun 14 Python
python基础学习之如何对元组各个元素进行命名详解
Jul 12 Python
Django基础三之视图函数的使用方法
Jul 18 Python
Python搭建代理IP池实现检测IP的方法
Oct 27 Python
tensorflow使用range_input_producer多线程读取数据实例
Jan 20 Python
Python Tricks 使用 pywinrm 远程控制 Windows 主机的方法
Jul 21 Python
关于Python不换行输出和不换行输出end=““不显示的问题(亲测已解决)
Oct 27 Python
Python word文本自动化操作实现方法解析
Nov 05 Python
python 实现一个图形界面的汇率计算器
Nov 09 Python
Python中常见的反爬机制及其破解方法总结
Jun 10 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环境――Appserv
2006/12/13 PHP
php xml实例 留言本
2009/03/20 PHP
解析php mysql 事务处理回滚操作(附实例)
2013/08/05 PHP
浅谈使用 Yii2 AssetBundle 中 $publishOptions 的正确姿势
2017/11/08 PHP
laravel实现上传图片,并且制作缩略图,按照日期存放的代码
2019/10/16 PHP
laravel实现图片上传预览,及编辑时可更换图片,并实时变化的例子
2019/11/14 PHP
为JS扩展Array.prototype.indexOf引发的问题探讨及解决
2013/04/24 Javascript
jquery 删除cookie失效的解决方法
2013/11/12 Javascript
createTextRange()的使用示例含文本框选中部分文字内容
2014/02/24 Javascript
Jquery异步提交表单代码分享
2015/03/26 Javascript
jQuery实现ctrl+enter(回车)提交表单
2015/10/19 Javascript
12个超实用的JQuery代码片段
2015/11/02 Javascript
关于JS Lodop打印插件打印Bootstrap样式错乱问题的解决方案
2016/12/23 Javascript
React服务端渲染(总结)
2017/07/01 Javascript
vue-router实现tab标签页(单页面)详解
2017/10/17 Javascript
使用vue 国际化i18n 实现多实现语言切换功能
2018/10/11 Javascript
在Vant的基础上实现添加表单验证框架的方法示例
2018/12/05 Javascript
详解Vue项目中实现锚点定位
2019/04/24 Javascript
Python 正则表达式入门(中级篇)
2016/12/07 Python
python中模块的__all__属性详解
2017/10/26 Python
Python3一行代码实现图片文字识别的示例
2018/01/15 Python
opencv与numpy的图像基本操作
2019/03/08 Python
Python循环结构的应用场景详解
2019/07/11 Python
Win10下python 2.7与python 3.7双环境安装教程图解
2019/10/12 Python
Pytorch之parameters的使用
2019/12/31 Python
python如何变换环境
2020/07/21 Python
Python同时迭代多个序列的方法
2020/07/28 Python
利用CSS3实现平移动画效果示例代码
2016/10/12 HTML / CSS
HTML5 b和i标记将被赋予真正的语义
2009/07/16 HTML / CSS
乡村文明行动实施方案
2014/03/29 职场文书
群众路线教育党课主持词
2014/04/01 职场文书
学校消防安全责任书
2014/07/23 职场文书
幼儿园感恩节活动总结
2015/03/24 职场文书
2019教师的学习计划
2019/06/25 职场文书
GPU服务器的多用户配置方法
2022/07/07 Servers
HTML中link标签属性的具体用法
2023/05/07 HTML / CSS