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 命令行参数sys.argv
Sep 06 Python
Python多线程编程(五):死锁的形成
Apr 05 Python
Python实现的飞速中文网小说下载脚本
Apr 23 Python
Python实现的朴素贝叶斯分类器示例
Jan 06 Python
python 实现求解字符串集的最长公共前缀方法
Jul 20 Python
python3判断url链接是否为404的方法
Aug 10 Python
Python图像处理实现两幅图像合成一幅图像的方法【测试可用】
Jan 04 Python
解决Django Haystack全文检索为空的问题
May 19 Python
如何基于python实现年会抽奖工具
Oct 20 Python
python 实用工具状态机transitions
Nov 21 Python
基于python+selenium自动健康打卡的实现代码
Jan 13 Python
Python 中面向接口编程
May 20 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
《心理测量者3》剧场版动画预告
2020/03/02 日漫
《星际争霸重制版》兵种对比图鉴
2020/03/02 星际争霸
消息持续发送的完整例子
2006/10/09 PHP
CI(CodeIgniter)模型用法实例分析
2016/01/20 PHP
PHP中的多种加密技术及代码示例解析
2016/10/20 PHP
yii gridview实现时间段筛选功能
2017/08/15 PHP
laravel实现于语言包的完美切换方法
2019/09/29 PHP
HR vs ForZe BO3 第二场 2.13
2021/03/10 DOTA
javascript 特殊字符串
2009/02/25 Javascript
JQuery Dialog的内存泄露问题解决方法
2010/06/18 Javascript
纯js和css实现渐变色包括静态渐变和动态渐变
2014/05/29 Javascript
JS实现网页游戏中滑块响应鼠标点击移动效果
2015/10/19 Javascript
以JavaScript来实现WordPress中的二级导航菜单的方法
2015/12/14 Javascript
jQuery自制提示框tooltip改进版
2016/08/01 Javascript
文件上传插件SWFUpload的使用指南
2016/11/29 Javascript
jquery实现图片平滑滚动详解
2017/03/22 jQuery
详解使用element-ui table组件的筛选功能的一个小坑
2018/11/02 Javascript
bootstrap table列和表头对不齐的解决方法
2019/07/19 Javascript
Vue实现数据请求拦截
2019/10/23 Javascript
基于js实现判断浏览器类型代码实例
2020/07/17 Javascript
详解Vue的mixin策略
2020/11/19 Vue.js
学习python (2)
2006/10/31 Python
基于Python中求和函数sum的用法详解
2018/06/28 Python
python 处理数字,把大于上限的数字置零实现方法
2019/01/28 Python
详解CSS3中强大的filter(滤镜)属性
2017/06/29 HTML / CSS
西班牙网上书店:Casa del Libro
2016/11/01 全球购物
马来西亚最大的在线隐形眼镜商店:MrLens
2019/03/27 全球购物
aden + anais英国官网:美国婴儿贴身用品品牌
2019/09/08 全球购物
Java软件工程师综合面试题笔试题
2013/09/08 面试题
《故乡》教学反思
2014/04/10 职场文书
促销活动总结模板
2014/07/01 职场文书
工会趣味活动方案
2014/08/18 职场文书
死亡诗社观后感
2015/06/05 职场文书
2016年幼儿园教研活动总结
2016/04/05 职场文书
教你部署vue项目到docker
2022/04/05 Vue.js
VUE解决跨域问题Access to XMLHttpRequest at
2022/05/06 Vue.js