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的ORM框架SQLAlchemy入门教程
Apr 28 Python
jupyter安装小结
Mar 13 Python
基于Python的文件类型和字符串详解
Dec 21 Python
Django中Forms的使用代码解析
Feb 10 Python
Pycharm更换python解释器的方法
Oct 29 Python
对python pandas 画移动平均线的方法详解
Nov 28 Python
django一对多模型以及如何在前端实现详解
Jul 24 Python
Django框架ORM数据库操作实例详解
Nov 07 Python
用python中的matplotlib绘制方程图像代码
Nov 21 Python
利用PyQt中的QThread类实现多线程
Feb 18 Python
python使用nibabel和sitk读取保存nii.gz文件实例
Jul 01 Python
pytorch fine-tune 预训练的模型操作
Jun 03 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
我的论坛源代码(五)
2006/10/09 PHP
json的键名为数字时的调用方式(示例代码)
2013/11/15 PHP
php技巧小结【推荐】
2017/01/19 PHP
解密效果
2006/06/23 Javascript
增强用户体验友好性之jquery easyui window 窗口关闭时的提示
2012/06/22 Javascript
JavaScript声明变量名的语法规则
2015/07/10 Javascript
jQuery和JavaScript节点插入元素的方法对比
2016/11/18 Javascript
JS使用面向对象技术实现的tab选项卡效果示例
2017/02/28 Javascript
Vue.Js中的$watch()方法总结
2017/03/23 Javascript
详解nodejs微信公众号开发——5.素材管理接口
2017/04/11 NodeJs
JavaScript实现form表单的多文件上传
2020/03/27 Javascript
Javascript循环删除数组中元素的几种方法示例
2017/05/18 Javascript
详解基于webpack2.x的vue2.x的多页面站点
2017/08/21 Javascript
对于input 框限定输入值为浮点型的js代码
2017/09/25 Javascript
vue中datepicker的使用教程实例代码详解
2019/07/08 Javascript
JavaScript面向对象程序设计中对象的定义和继承详解
2019/07/29 Javascript
javascript实现搜索筛选功能实例代码
2020/11/12 Javascript
简述Python2与Python3的不同点
2018/01/21 Python
Pandas中把dataframe转成array的方法
2018/04/13 Python
python print 按逗号或空格分隔的方法
2018/05/02 Python
详解Python读取yaml文件多层菜单
2019/03/23 Python
python 实现分组求和与分组累加求和代码
2020/05/18 Python
详解CSS3伸缩布局盒模型Flex布局
2018/08/20 HTML / CSS
可能这些是你想要的H5软键盘兼容方案(小结)
2019/04/23 HTML / CSS
植村秀美国官网:Shu Uemura美国
2019/03/19 全球购物
英国运动风奢侈品购物网站:Maison De Fashion
2020/08/28 全球购物
小车司机岗位职责
2013/11/25 职场文书
焦裕禄精神心得体会
2014/09/02 职场文书
学习教师法的心得体会
2014/09/03 职场文书
购房委托书范本
2014/09/18 职场文书
干部个人考察材料
2014/12/24 职场文书
社区义诊通知
2015/04/24 职场文书
培训班开班主持词
2015/07/02 职场文书
母亲节主题班会
2015/08/14 职场文书
postgresql 删除重复数据案例详解
2021/08/02 PostgreSQL
nginx服务器的下载安装与使用详解
2021/08/02 Servers