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 相关文章推荐
py中的目录与文件判别代码
Jul 16 Python
Python3实现将文件树中所有文件和子目录归档到tar压缩文件的方法
May 22 Python
Python实现将xml导入至excel
Nov 20 Python
Python读取一个目录下所有目录和文件的方法
Jul 15 Python
基于Python的关键字监控及告警
Jul 06 Python
Python读取word文本操作详解
Jan 22 Python
基于python traceback实现异常的获取与处理
Dec 13 Python
torch 中各种图像格式转换的实现方法
Dec 26 Python
pytorch中 gpu与gpu、gpu与cpu 在load时相互转化操作
May 25 Python
python求解汉诺塔游戏
Jul 09 Python
Django REST Framework 分页(Pagination)详解
Nov 30 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
《Re:从零开始的异世界生活》剧情体验,手游新作定名
2020/04/09 日漫
一个php作的文本留言本的例子(三)
2006/10/09 PHP
PHP VS ASP
2006/10/09 PHP
PHP 自定义错误处理函数trigger_error()
2013/03/26 PHP
PHP删除目录及目录下所有文件的方法详解
2013/06/06 PHP
PHP Reflection API详解
2015/05/12 PHP
PHP导入导出Excel代码
2015/07/07 PHP
jquery进行数组遍历如何跳出当前的each循环
2014/06/05 Javascript
使用Meteor配合Node.js编写实时聊天应用的范例
2015/06/23 Javascript
JavaScript获得指定对象大小的方法
2015/07/01 Javascript
详解vue-cli与webpack结合如何处理静态资源
2017/09/19 Javascript
node.js中http模块和url模块的简单介绍
2017/10/06 Javascript
vue2.0与bootstrap3实现列表分页效果
2017/11/28 Javascript
Vue项目部署在Spring Boot出现页面空白问题的解决方案
2018/11/26 Javascript
VUE搭建手机商城心得和遇到的坑
2019/02/21 Javascript
vue+element实现图片上传及裁剪功能
2020/06/29 Javascript
vue组件中节流函数的失效的原因和解决方法
2020/12/02 Vue.js
python读取二进制mnist实例详解
2017/05/31 Python
python批量修改文件编码格式的方法
2018/05/31 Python
python web自制框架之接受url传递过来的参数实例
2018/12/17 Python
Python 实用技巧之利用Shell通配符做字符串匹配
2019/08/23 Python
简单分析python的类变量、实例变量
2019/08/23 Python
python计算二维矩形IOU实例
2020/01/18 Python
浅谈基于Canvas的手绘风格图形库Rough.js
2018/03/19 HTML / CSS
Booking.com西班牙:全球酒店预订
2018/03/30 全球购物
材料物理专业个人求职信
2013/12/15 职场文书
报到证丢失证明
2014/01/11 职场文书
《九寨沟》教学反思
2014/04/08 职场文书
数据保密承诺书
2014/06/03 职场文书
11.9消防日宣传标语
2014/10/08 职场文书
2019教师的学习计划
2019/06/25 职场文书
python中pandas.read_csv()函数的深入讲解
2021/03/29 Python
如何在Python中创建二叉树
2021/03/30 Python
MongoDB balancer的使用详解
2021/04/30 MongoDB
MySQL系列之开篇 MySQL关系型数据库基础概念
2021/07/02 MySQL
springboot集成redis存对象乱码的问题及解决
2022/06/16 Java/Android