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 相关文章推荐
举例讲解Django中数据模型访问外键值的方法
Jul 21 Python
Python实现压缩与解压gzip大文件的方法
Sep 18 Python
如何用itertools解决无序排列组合的问题
May 18 Python
Python字符串处理实现单词反转
Jun 14 Python
python中文分词,使用结巴分词对python进行分词(实例讲解)
Nov 14 Python
基于随机梯度下降的矩阵分解推荐算法(python)
Aug 31 Python
django解决跨域请求的问题
Nov 11 Python
使用Flask-Cache缓存实现给Flask提速的方法详解
Jun 11 Python
Python使用python-docx读写word文档
Aug 26 Python
在python中利用pycharm自定义代码块教程(三步搞定)
Apr 15 Python
python Paramiko使用示例
Sep 21 Python
python遍历路径破解表单的示例
Nov 21 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
thinkphp四种url访问方式详解
2014/11/28 PHP
php实现文本数据导入SQL SERVER
2015/05/17 PHP
PHP使用MPDF类生成PDF的方法
2015/12/08 PHP
Yii2隐藏frontend/web和backend/web的方法
2015/12/12 PHP
jQuery 学习6 操纵元素显示效果的函数
2010/02/07 Javascript
jQuery温习篇 强大的JQuery选择器
2010/04/24 Javascript
Textarea与懒惰渲染实现代码
2012/01/04 Javascript
js函数中onmousedown和onclick的区别和联系探讨
2013/05/19 Javascript
使用js实现数据格式化
2014/12/03 Javascript
JavaScript的类型、值和变量小结
2015/07/09 Javascript
基于jquery实现轮播特效
2016/04/22 Javascript
Vue.js 2.0 和 React、Augular等其他前端框架大比拼
2016/10/08 Javascript
jQuery插件WebUploader实现文件上传
2016/11/07 Javascript
仿iframe效果Aajx文件上传实例
2016/11/18 Javascript
JS正则RegExp.test()使用注意事项(不具有重复性)
2016/12/28 Javascript
vue实现一个炫酷的日历组件
2018/10/08 Javascript
nodejs初始化init的示例代码
2018/10/10 NodeJs
vue微信分享出来的链接点开是首页问题的解决方法
2018/11/28 Javascript
浅谈Vue组件单元测试究竟测试什么
2020/02/05 Javascript
Vue 实现可视化拖拽页面编辑器
2021/02/01 Vue.js
运动检测ViBe算法python实现代码
2018/01/09 Python
python3 破解 geetest(极验)的滑块验证码功能
2018/02/24 Python
详解pandas安装若干异常及解决方案总结
2019/01/10 Python
Django 请求Request的具体使用方法
2019/11/11 Python
全球知名提供各类营养保健品的零售商:Vitamin Shoppe
2016/10/09 全球购物
美国第一香水网站:Perfume.com
2017/01/23 全球购物
Shopbop中文官网:美国亚马逊旗下时尚购物网站
2020/12/15 全球购物
Nobody Denim官网:购买高级女士牛仔裤
2021/03/15 全球购物
计算机开发个人求职信范文
2013/09/26 职场文书
《阳光》教学反思
2014/02/23 职场文书
文明礼仪伴我行演讲稿
2014/05/12 职场文书
小学生常见病防治方案
2014/06/06 职场文书
财务经理岗位职责范本
2015/04/08 职场文书
学生党支部工作总结2015
2015/05/26 职场文书
简短的人生哲理(38句)
2019/08/13 职场文书
Pandas||过滤缺失数据||pd.dropna()函数的用法说明
2021/05/14 Python