django 扩展User

环境

Python 3.5.1

django 1.9.1

前言

今天用django写web平台,第一时间想到django自带的认证,连session都提供好了,既然有轮子了,我们就不需要自己造了。

需求

注册登录都有现成的代码,主要是自带的User字段只有(email,username,password),所以需要扩展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不能为空",})

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)

查看源码发现是check_password的方法是用hash进行校验,之前注册的password写法是

user.password=password

这种写法是明文入库,需要更改密码的入库写法

user.set_password(password)
时间: 2025-01-05 06:10:48

django 扩展User的相关文章

ValueError: Related model 'myapp.ExUser' cannot be resolved django扩展User字段

扩展字段目前有两种方法: 扩展字段 新建一张表->然后与原有表创建一对一关系 继承django.contrib.auth.models下的AbstractUser类 ,重写User类 两种方式都是官方文档提到的,,实现方法可以在官网以及搜索引擎搜到各大佬的博客上,我今天只分享一下自己遇到的问题及解决方法 我采用的是第2种, 重写User的方法,但是在迁移数据库的时候,遇到问题, 编写好其它表之后,发现User表中字段需要添加于是在models.py 文件中添加了 ExUser类 from dja

Django扩展自定义manage命令

使用django开发,对python manage.py ***命令模式肯定不会陌生.比较常用的有runserver,migrate... 本文讲述如何自定义扩展manage命令. 1.源码分析 manage.py文件是通过django-admin startproject project_name生成的. 1)manage.py的源码 a)首先设置了settings文件,本例中CIServer指的是project_name. b)其次执行了一个函数django.core.management.

django 扩展自带权限,使其支持对象权限

扩展django 自带权限 说明 在不重写 自带权限的基础上,完成支持对象权限,适用于小型项目.欢迎提出修改意见 软件支持 jsonfield 数据库 新建3个表 from django.db import models from django.contrib.auth.models import AbstractUser, Group ,User from jsonfield import JSONField class Request(models.Model): request = mod

Django扩展内置User类

内置User类 使用内置User可以方便实现登录验证,利用Admin管理界面还可以方便添加.删除.修改用户. 一个内置的User类定义了以下字段: username: 用户名 password: 密码 first_name: 姓名first last_name: 姓名last email: 邮箱 groups: Group类多对多的关系对象管理器 user_permissions: Permission类多对多的关系对象管理器 is_staff: 是否工作人员 is_active: 是否激活 i

django扩展用户一对一关联

1.app01/models.py里面创建模型UserExtension, 一对一关联User from django.db import models from django.contrib.auth.models import User from django.dispatch import receiver from django.db.models.signals import post_save class UserExtension(models.Model): user = mod

Django扩展

一.文件上传 当Django在处理文件上传的时候,文件数据被保存在request.FILES FILES中的每个键为<input type="file" name="" />中的name 注意:FILES只有在请求的方法为POST 且提交的<form>带有enctype="multipart/form-data" 的情况下才会包含数据.否则,FILES 将为一个空的类似于字典的对象 使用模型处理上传文件:将属性定义成mod

django扩展User表

1. 继承AbstractUser: 在你对应的your_app/models.py文件添加 from django.contrib.auth.models import AbstractUser #自定义你想要的字段 class User(AbstractUser): faculty = models.ForeignKey(Faculty, on_delete=models.SET_NULL, default=None, null=True) major = models.ForeignKey

django扩展User模型(model),profile

from django.contrib.auth.models import User # Create your models here. class Profile(models.Model): user = models.OneToOneField(User, related_name='profile') date_of_birth = models.DateTimeField(blank=True, null=True) photo = models.ImageField(upload

django扩展User认证系统

第一种方法proxy 如果你对Django提供的字段,以及验证的方法都比较满意,没有什么需要改的.但是只是需要在他原有的基础之上增加一些操作的方法.那么建议使用这种方式.示例代码如下: #在model.py下 class Person(User): class Meta: proxy = True def get_blacklist(self): return self.objects.filter(is_active=False) 在以上,我们定义了一个Person类,让他继承自User,并且