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 相关文章推荐
在Linux上安装Python的Flask框架和创建第一个app实例的教程
Mar 30 Python
Python中最大最小赋值小技巧(分享)
Dec 23 Python
python使用Plotly绘图工具绘制气泡图
Apr 01 Python
Django生成PDF文档显示在网页上以及解决PDF中文显示乱码的问题
Jul 04 Python
python3 下载网络图片代码实例
Aug 27 Python
python3实现elasticsearch批量更新数据
Dec 03 Python
Python3 使用selenium插件爬取苏宁商家联系电话
Dec 23 Python
解析PyCharm Python运行权限问题
Jan 08 Python
通过python连接Linux命令行代码实例
Feb 18 Python
手把手教你安装Windows版本的Tensorflow
Mar 26 Python
pycharm 代码自动补全的实现方法(图文)
Sep 18 Python
LyScript实现绕过反调试保护的示例详解
Aug 14 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 程式大小
2006/12/06 PHP
php查看session内容的函数
2008/08/27 PHP
使用PHP会话(Session)实现用户登陆功能
2013/06/29 PHP
php实现表单多按钮提交action的处理方法
2015/10/24 PHP
PHP利用imagick生成组合缩略图
2016/02/19 PHP
PHP实现阿里大鱼短信验证的实例代码
2017/07/10 PHP
Laravel框架路由设置与使用示例
2018/06/12 PHP
TNC vs BOOM BO3 第一场2.13
2021/03/10 DOTA
jQuery之end()和pushStack()使用介绍
2012/02/07 Javascript
将字符串转换成gb2312或者utf-8编码的参数(js版)
2013/04/10 Javascript
ExtJS DOM元素操作经验分享
2013/08/28 Javascript
详解JavaScript语法对{}处理的坑爹之处
2014/06/05 Javascript
js跨域问题浅析及解决方法优缺点对比
2014/11/08 Javascript
jQuery实现页面内锚点平滑跳转特效的方法总结
2015/05/11 Javascript
jquery mobile移动端幻灯片滑动切换效果
2020/04/15 Javascript
Bootstrap列表组学习使用
2017/02/09 Javascript
浅谈使用React.setState需要注意的三点
2017/12/18 Javascript
AngularJS双向数据绑定原理之$watch、$apply和$digest的应用
2018/01/30 Javascript
vue.extend与vue.component的区别和联系
2018/09/19 Javascript
基于vue和react的spa进行按需加载的实现方法
2018/09/29 Javascript
微信小程序实现的绘制table表格功能示例
2019/04/26 Javascript
Vue程序化的事件监听器(实例方案详解)
2020/01/07 Javascript
Vue + Scss 动态切换主题颜色实现换肤的示例代码
2020/04/27 Javascript
python+opencv实现动态物体识别
2018/01/09 Python
python基础教程项目四之新闻聚合
2018/04/02 Python
mvc框架打造笔记之wsgi协议的优缺点以及接口实现
2018/08/01 Python
对Python3 解析html的几种操作方式小结
2019/02/16 Python
python程序 创建多线程过程详解
2019/09/23 Python
python 通过视频url获取视频的宽高方式
2019/12/10 Python
美国亚马逊旗下男装网站:East Dane(支持中文)
2019/09/25 全球购物
计算机毕业大学生推荐信
2013/12/01 职场文书
销售经理工作职责
2014/02/03 职场文书
中学优秀班主任事迹材料
2014/05/01 职场文书
道歉情书大全
2015/05/12 职场文书
离职证明格式样本
2015/06/12 职场文书
全面盘点MySQL中的那些重要日志文件
2021/11/27 MySQL