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之有点简约的元组
Sep 24 Python
Python操作列表之List.insert()方法的使用
May 20 Python
python中requests爬去网页内容出现乱码问题解决方法介绍
Oct 25 Python
linecache模块加载和缓存文件内容详解
Jan 11 Python
浅谈Python中的zip()与*zip()函数详解
Feb 24 Python
解决python "No module named pip" 的问题
Oct 13 Python
python实现任意位置文件分割的实例
Dec 14 Python
Python中的random.uniform()函数教程与实例解析
Mar 02 Python
简单了解为什么python函数后有多个括号
Dec 19 Python
Window版下在Jupyter中编写TensorFlow的环境搭建
Apr 10 Python
Python读取图像并显示灰度图的实现
Dec 01 Python
Python jiaba库的使用详解
Nov 23 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 上传文件大小限制
2009/07/05 PHP
php pack与unpack 摸板字符字符含义
2009/10/29 PHP
关于查看MSSQL 数据库 用户每个表 占用的空间大小
2013/06/21 PHP
关于zend studio 出现乱码问题的总结
2013/06/23 PHP
PHP实现微信商户支付企业付款到零钱功能
2018/09/30 PHP
php生成短网址/短链接原理和用法实例分析
2020/05/29 PHP
CutePsWheel javascript libary 控制输入文本框为可使用滚轮控制的js库
2010/02/07 Javascript
获取客户端网卡MAC地址和IP地址实现JS代码
2013/03/17 Javascript
js导入导出excel(实例代码)
2013/11/25 Javascript
jQuery实现的省市联动菜单功能示例【测试可用】
2017/01/13 Javascript
js实现简单的获取验证码按钮效果
2017/03/03 Javascript
fckeditor部署到weblogic出现xml无法读取及样式不能显示问题的解决方法
2017/03/24 Javascript
详解webpack和webpack-simple中如何引入css文件
2017/06/28 Javascript
Bootstrap-table自定义可编辑每页显示记录数
2018/09/07 Javascript
vue项目中使用bpmn为节点添加颜色的方法
2020/04/30 Javascript
js中实现继承的五种方法
2021/01/25 Javascript
Python使用MD5加密字符串示例
2014/08/22 Python
python中sets模块的用法实例
2014/09/30 Python
python操作ssh实现服务器日志下载的方法
2015/06/03 Python
Python聚类算法之基本K均值实例详解
2015/11/20 Python
Python实现读取文件最后n行的方法
2017/02/23 Python
python学习入门细节知识点
2018/03/29 Python
Python 实现文件打包、上传与校验的方法
2019/02/13 Python
Python中函数参数匹配模型详解
2019/06/09 Python
Django urls.py重构及参数传递详解
2019/07/23 Python
python禁用键鼠与提权代码实例
2019/08/16 Python
Flask中endpoint的理解(小结)
2019/12/11 Python
python属于哪种语言
2020/08/16 Python
Python3.9新特性详解
2020/10/10 Python
音乐教学反思
2014/02/02 职场文书
《花木兰》教学反思
2014/04/09 职场文书
小学生手册家长评语
2014/04/16 职场文书
2014最新开业庆典策划方案(5篇)
2014/09/15 职场文书
劳动仲裁代理词范文
2015/05/25 职场文书
OpenCV-Python实现人脸磨皮算法
2021/06/07 Python
Python+pyaudio实现音频控制示例详解
2022/07/23 Python