• django 认证登录


    AbstractUser
    from django.contrib.auth.models import AbstractUser AbstractBaseUser中只含有3个field: password, last_login和is_active. 这个就是你自己高度定制自己需要的东西

    什么是基于扩展AbstractBaseUser来创建的自定义用户模型?

    它是继承于AbstractBaseUser类的一个全新的用户系统。这需要通过settings.py进行特别的维护和更新一些相关的文件。理想的情况是,它在项目开始时就已经被设计,因为它对数据库架构影响很大。在执行时都需要额外的维护。

    什么时候需要扩展AbstractBaseUser类自定义用户模型呢?

    当应用对验证过程具有特殊要求时,那么需要自定义一个用户模型。比如,在一些将邮件地址代替用户名作为验证令牌的情况时,自定义用户模型更合适。

    方法4:扩展AbstractUser来创建自定义用户模型

    什么是基于扩展AbstractUser创建的自定义用户模型?

    它是继承于AbstractUser类的一个全新的用户系统。它也需要通过settings.py进行特别的维护和更新一些相关的文件。理想的情况是,它在项目开始之前就已经被设计,因为它对数据库架构影响很大。在执行时需要额外的维护。

    什么时候需要扩展AbstractBaseUser类的自定义用户模型呢?

    当你对Django处理身份验证过程很满意而又不会改动它时,那可以使用它。或者,你想直接在用户模型中增加一些额外的信息而不想创建新的类时,也可以使用它。
    is_staff
    是否允许user访问admin界面

    is_active
    用户是否活跃。

    一、重写user,将新的user注册到admin,还要重写认证
    二、继承user,进行扩展(记得在settings中设置AUTH_USER_MODEL

    settings.py 设置AUTH_USER_MODEL = "myapp.NewUser"

    # Custom User Auth model
    AUTH_USER_MODEL = 'users.User'

    2.1 继承AbstractUser类

    from django.contrib.auth.models import AbstractUser
    from django.utils.translation import ugettext_lazy as _
    from django.db import models
    from django.conf import settings
    from . import UserGroup
    
    
    __all__ = ['User']
    
    class User(AbstractUser):
        ROLE_CHOICES = (
            ('Admin', _('Administrator')),
            ('User', _('User')),
            ('App', _('Application'))
        )
    
        username = models.CharField(max_length=20, unique=True, verbose_name=_('Username'))
        name = models.CharField(max_length=20, verbose_name=_('Name'))
        email = models.EmailField(max_length=30, unique=True, verbose_name=_('Email'))
        groups = models.ManyToManyField(UserGroup, related_name='users', blank=True, verbose_name=_('User group'))
        role = models.CharField(choices=ROLE_CHOICES, default='User', max_length=10, blank=True, verbose_name=_('Role'))
        is_first_login = models.BooleanField(default=False)
        comment = models.TextField(max_length=200, blank=True, verbose_name=_('Comment'))
        created_by = models.CharField(max_length=30, default='', verbose_name=_('Created by'))
    
    
        @property
        def is_superuser(self):
            if self.role == 'Admin':
                return True
            else:
                return False
    
        @is_superuser.setter
        def is_superuser(self, value):
            if value is True:
                self.role = 'Admin'
            else:
                self.role = 'User'
    
        @property
        def is_staff(self):
            if self.is_authenticated and self.is_valid:
                return True
            else:
                return False
    
        @is_staff.setter
        def is_staff(self, value):
            pass

    踩过的坑:
    1、登陆的时候用自带的认证模块总是报none

    user = authenticate(username=username, password=password)

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

    user.password=password

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

    user.set_password(password)

    form 设置

    from django import forms
    from django.contrib.auth.forms import AuthenticationForm
    from django.utils.translation import gettext_lazy as _
    
    
    class UserLoginForm(AuthenticationForm):
        username = forms.CharField(label=_('Username'), max_length=100)
        password = forms.CharField(
            label=_('Password'), widget=forms.PasswordInput, max_length=100,
            strip=False)

    AuthenticationForm登录表单
    用于用户登录的表单。
    默认情况下,AuthenticationForm 将拒绝is_active 标志为False 的用户。

    login.py配置

    from django.shortcuts import render,HttpResponse
    from django.shortcuts import reverse, redirect
    from django.contrib.auth import login as auth_login, logout as auth_logout
    from django.utils.decorators import method_decorator
    from django.views.decorators.csrf import csrf_protect
    from django.views.generic.edit import FormView
    from .. import forms
    from django.views.decorators.cache import never_cache
    from django.views.decorators.debug import sensitive_post_parameters
    
    
    @method_decorator(csrf_protect, name='dispatch')
    class UserLoginView(FormView):
        template_name = 'users/login.html'
        form_class = forms.UserLoginForm
        redirect_field_name = 'next'
    
        def get(self, request, *args, **kwargs):
            if request.user.is_staff:
                return redirect(self.get_success_url())
            return super(UserLoginView, self).get(request, *args, **kwargs)
    
        def form_valid(self, form):
            auth_login(self.request, form.get_user())
            return redirect(self.get_success_url())
    
        def get_success_url(self):
            if self.request.user.is_first_login:
                return reverse('users:user-first-login')
    
            return self.request.POST.get(
                self.redirect_field_name,
                self.request.GET.get(self.redirect_field_name, reverse('index')))

    登陆login

    login()

    登陆函数,需要一个HttpRequest对象和一个User对象作参数。login()使用django的session框架,将User的id存储在session中。

    同时使用authenticate()和login():

    from django.contrib.auth import authenticate, login
     
    def my_view(request):
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                # Redirect to a success page.
            else:
                # Return a 'disabled account' error message
        else:
            # Return an 'invalid login' error message.

    如果不知道密码,login方法:

    user=MyUser.objects.get(...)
    user.backend = 'django.contrib.auth.backends.ModelBackend'
    login(request,user)

    FormView使用基于类的视图处理表单 表单的处理通常有3 个步骤:

    • 初始的GET (空白或预填充的表单)
    • 带有非法数据的POST(通常重新显示表单和错误信息)
    • 带有合法数据的POST(处理数据并重定向) 使用FormView 来构造其视图:
    from myapp.forms import ContactForm
    from django.views.generic.edit import FormView
    
    class ContactView(FormView):
        template_name = 'contact.html'
        form_class = ContactForm
        success_url = '/thanks/'
    
        def form_valid(self, form):
            # This method is called when valid form data has been POSTed.
            # It should return an HttpResponse.
            form.send_email()
            return super(ContactView, self).form_valid(form)

    html设置:

    {% load static %}
    {% load i18n %}
    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title> JumpServer </title>
        <link rel="shortcut icon" href="{% static "img/facio.ico" %}" type="image/x-icon">
        {% include '_head_css_js.html' %}
        <link href="{% static "css/jumpserver.css" %}" rel="stylesheet">
        <script src="{% static "js/jumpserver.js" %}"></script>
        <style>
            .captcha {
                 float: right;
             }
        </style>
    </head>
    
    <body class="gray-bg">
        <div class="loginColumns animated fadeInDown">
            <div class="row">
                <div class="col-md-6">
                </div>
                <div class="col-md-6">
                    <div class="ibox-content">
                        <div><img src="{% static 'img/logo.png' %}" width="82" height="82"> <span class="font-bold text-center" style="font-size: 32px; font-family: inherit">{% trans 'Login' %}</span></div>
                        <form class="m-t" role="form" method="post" action="">
                            {% csrf_token %}
                            {% if form.errors %}
                                {% if 'captcha' in form.errors %}
                                    <p class="red-fonts">{% trans 'Captcha invalid' %}</p>
                                {% else %}
                                    <p class="red-fonts">{{ form.non_field_errors.as_text }}</p>
                                {% endif %}
                            {% endif %}
                            <div class="form-group">
                                <input type="text" class="form-control" name="{{ form.username.html_name }}" placeholder="{% trans 'Username' %}" required="">
                            </div>
                            <div class="form-group">
                                <input type="password" class="form-control" name="{{ form.password.html_name }}" placeholder="{% trans 'Password' %}" required="">
                            </div>
                            <div>
    {#                            {{ form.captcha }}#}
                            </div>
                            <button type="submit" class="btn btn-primary block full-width m-b">{% trans 'Login' %}</button>
    
    {#                        <a href="{% url 'users:forgot-password' %}">#}
                                <small>{% trans 'Forgot password' %}?</small>
                            </a>
    
                            <p class="text-muted text-center">
                            </p>
                        </form>
                        <p class="m-t">
                        </p>
                    </div>
                </div>
            </div>
            <hr/>
            <div class="row">
                <div class="col-md-6">
                    Copyright Jumpserver.org
                </div>
                <div class="col-md-6 text-right">
                   <small>© 2014-2017</small>
                </div>
            </div>
        </div>
    </body>
    </html>

    生成表信息如下:

    id	password	last_login	first_name	last_name	is_active	data_joined	username	name	email	role	comment	created_bt	is_first_login
    1	pbkdf2_sha256$30000$f8HLJLRwydBR$M+X1huSgQOojfaG01SGNBYPOlbYnHHw/A4/RdcSBEQQ=	11/6/2017 18:55:52	1		1	11/5/2017 18:56:05	admin	Administrator	a
  • 相关阅读:
    javascript模态窗体各种用法(转)
    AjaxControlToolKit之ConfirmButton效果用法
    AjaxControlToolKit之AutoCompleteExtender用法
    文章,记录按内容分页显示,根据文章内容按字数进行分页(转)
    AjaxControlToolKit之DragPanelExtender用法
    prototype.js 1.4版开发者手册(强烈推荐) (转自http://fredren.javaeye.com/blog/112479)
    JS拖动技术 关于setCapture (转自 剑胆琴心.Net学习笔记)
    Javascript 如何实现对象的拖动?(转自闪吧)
    phpsprintf、echo、print、printf 简单
    phpxdebug配置 简单
  • 原文地址:https://www.cnblogs.com/patrick0715/p/7810278.html
Copyright © 2020-2023  润新知