zoukankan      html  css  js  c++  java
  • 8 实现10mins用户登录与注册

    1。重新认识登录

     

     

    2。实现登录功能

     

    (1)Django 自带的authenticate, login模块

    from django.contrib.auth import authenticate, login
    

      

    表单获取用户名,密码
    
    用户名,密码放到authenticate校验
    
    login注册
    
    小卡片发送给浏览器
    

      

    (2)表单生成

     (3)view视图模型

    • 取出user,paswd
    • 放入authenticate函数验证
    • 验证成功登录

    from django.shortcuts import render, Http404,redirect,HttpResponse
    from  website.models import  Video
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    from django.contrib.auth import authenticate, login
    from website.form import LoginForm
    # Create your views here.
    
    def index_login(request):
        context = {}
        if request.method == "GET":
            form = LoginForm
        if request.method == "POST":
            form = LoginForm(request.POST)
            if form.is_valid():
                username = form.cleaned_data('username')   #取出数据
                password = form.cleaned_data('password')
                user = authenticate(username=username, password=password)  #authenticate函数
    
                #验证用户对象  如果是真,就True
                if user:
                    login(request, user)
                    return redirect(to='list')
                else:
                    return HttpResponse('<h1>Not this User</h1>')
    
        context['form'] = form
        return render(request, 'register_login.html', context)
    

      

    (3)authenticate源码
    def authenticate(**credentials):
        """
        If the given credentials are valid, return a User object.
        """
        for backend, backend_path in _get_backends(return_tuples=True):
            try:
                inspect.getcallargs(backend.authenticate, **credentials)
            except TypeError:
                # This backend doesn't accept these credentials as arguments. Try the next one.
                continue
    
            try:
                user = backend.authenticate(**credentials)
            except PermissionDenied:
                # This backend says to stop in our tracks - this user should not be allowed in at all.
                return None
            if user is None:
                continue
            # Annotate the user object with the path of the backend.
            user.backend = backend_path
            return user
    
        # The credentials supplied are invalid to all backends, fire signal
        user_login_failed.send(sender=__name__,
                credentials=_clean_credentials(credentials))
    

      

      (4)login函数源码

    def login(request, user):
        """
        Persist a user id and a backend in the request. This way a user doesn't
        have to reauthenticate on every request. Note that data set during
        the anonymous session is retained when the user logs in.
        """
        session_auth_hash = ''
        if user is None:
            user = request.user
        if hasattr(user, 'get_session_auth_hash'):
            session_auth_hash = user.get_session_auth_hash()
    
        if SESSION_KEY in request.session:
            if _get_user_session_key(request) != user.pk or (
                    session_auth_hash and
                    request.session.get(HASH_SESSION_KEY) != session_auth_hash):
                # To avoid reusing another user's session, create a new, empty
                # session if the existing session corresponds to a different
                # authenticated user.
                request.session.flush()
        else:
            request.session.cycle_key()
        request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
        request.session[BACKEND_SESSION_KEY] = user.backend
        request.session[HASH_SESSION_KEY] = session_auth_hash
        if hasattr(request, 'user'):
            request.user = user
        rotate_token(request)
        user_logged_in.send(sender=user.__class__, request=request, user=user)
    

      

       (5)url

    from django.conf.urls import url
    from django.contrib import admin
    from website.views import listing,index_login
    from django.conf import settings
    from django.conf.urls.static import static
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^list/$', listing, name='list'),
        url(r'^list/(?P<cate>[A-Za-z]+)$', listing, name='list'),  #cate 变量
        url(r'^login/$', index_login, name='login'), 
    ]
    

      

       (6)Template层:表单渲染

    •   缺少post方法

    • login.html登录页面
    <!DOCTYPE html>
    {% load staticfiles %}
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <link rel="stylesheet" href="../static/css/semantic.css" media="screen" title="no title" charset="utf-8">
            <link href="https://fonts.googleapis.com/css?family=Play" rel="stylesheet">
    
        </head>
    
        <style type="text/css">
            body {
                background: url(../static/images/super_blur_back2.jpg);
                background-size: cover;
            }
    
            .ui.grid.divided.segment.container{
                height: 400px;
                width:600px !important;
                border:rgba(255, 0, 0, 0);
                position: absolute;
                left: 50%;
                top:40%;
                transform: translate(-50%,-50%);
            }
    
            .five.wide.column {
                background: url(../static/images/red_regi.jpg);
                background-size: cover;
                background-position: 60% 0%;
            }
    
            form {
                margin-top: 60px;
            }
            h1,h3,h4{
                font-family: 'Play', sans-serif !important;
    
            }
        </style>
    
        <body>
            <div class="ui grid divided segment container">
                <div class="five wide  column">
    
                    <h4 class="ui inverted header">
    
                        <i class="angle left  icon"></i>
                    </h4>
    
                    <h1 class="ui inverted center aligned header" style="font-size: 40px;margin-top:55px">
                        <p class="sub header">
                            Welcome to
                        </p>
                        10MINs
                    </h1>
    
    
    
                </div>
    
                <div class="eleven wide column">
                    <h4 class="ui inverted right aligned header">
                        <a href="#" style="color:#ff695e;">or LOGIN</a>
                    </h4>
    
                    <form class="ui form" method="post">
                        {{ form }}
                        {% csrf_token %}
                      <button class="ui inverted red circular right floated button" type="submit">Done</button>
                    </form>
    
                </div>
            </div>
        </body>
    </html>
    View Code

      (7)演示登录

     

     

      (8)sessionid唯一身份令牌

     

      (9)登录登出修改,没有请求用户身份的判断

    <div class="right menu">
              {% if request.user.is_authenticated %}
                  <div class="item">
                      <h5 class="ui inverted header">
                              <div class="ui mini circular image">
                                  <img src="../static/images/hou30.jpg" alt="">
                              </div>
                              <span>{{ request.user.username }}</span>
                      </h5>
                  </div>
                  <div class="item">
                      <a href="#logout/" class="ui inverted circular button">Logout</a>
                  </div>
    
              {% else %}
    
                  <div class="item">
                      <h5 class="ui inverted header">
                              <div class="ui mini circular image">
                                  <img src="../static/images/hou30.jpg" alt="">
                              </div>
                              <span>{{ request.user.username }}</span>
                      </h5>
                  </div>
                  <div class="item">
                      <a href="#logout/" class="ui inverted circular button">Signup/Login</a>
                  </div>
    
              {% endif %}
    
            </div>
    

      

      (10) 登录演示,登出演示 

     

      3.扩展资料后的用户判断

     

    •    Django中的model.user模型,官方不建议修改,可以扩展

    •  扩展用户的上传头像

      (1) Model:添加用户资料表

    from django.db import models
    from faker import Factory
    from django.contrib.auth.models import User
    
    class UserProfile(models.Model):
        """用户资料类"""
        belong_to = models.OneToOneField(to=User, related_name='profile')
        profile_image = models.FileField(upload_to='profile_image')
    

      

      (2)admin注册

    from django.contrib import admin
    from website.models import Video,UserProfile
    # Register your models here.
    
    admin.site.register(Video)
    admin.site.register(UserProfile)
    

      

      (3)更新数据库

       (4)上传图像

      (5)Template层:listing.html 显示个人头像

     

                              <div class="ui mini circular image">
                                
                                {% if request.user.profile.profile_image %}    
                                
                                  <img src="/upload/{{ request.user.profile.profile_image }}" alt="" />
                                {% else %}
                                  <img src="../static/images/hou30.jpg" alt="">
                                {% endif %}
    
                              </div>
    

      

    4.实现登出功能

    • Django核心表单的模块:
    • 创建用户(注册用),登录
    from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
    

      

      (2)查看源码文件:

    class AuthenticationForm(forms.Form):
        """
        Base class for authenticating users. Extend this to get a form that accepts
        username/password logins.
        """
        username = forms.CharField(max_length=254)
        password = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
    
        error_messages = {
            'invalid_login': _("Please enter a correct %(username)s and password. "
                               "Note that both fields may be case-sensitive."),
            'inactive': _("This account is inactive."),
        }
    
        def __init__(self, request=None, *args, **kwargs):
            """
            The 'request' parameter is set for custom auth use by subclasses.
            The form data comes in via the standard 'data' kwarg.
            """
            self.request = request
            self.user_cache = None
            super(AuthenticationForm, self).__init__(*args, **kwargs)
    
            # Set the label for the "username" field.
            UserModel = get_user_model()
            self.username_field = UserModel._meta.get_field(UserModel.USERNAME_FIELD)
            if self.fields['username'].label is None:
                self.fields['username'].label = capfirst(self.username_field.verbose_name)
    
        def clean(self):
            username = self.cleaned_data.get('username')
            password = self.cleaned_data.get('password')
    
            if username and password:
                self.user_cache = authenticate(username=username,
                                               password=password)
                if self.user_cache is None:
                    raise forms.ValidationError(
                        self.error_messages['invalid_login'],
                        code='invalid_login',
                        params={'username': self.username_field.verbose_name},
                    )
                else:
                    self.confirm_login_allowed(self.user_cache)
    
            return self.cleaned_data
    
        def confirm_login_allowed(self, user):
            """
            Controls whether the given User may log in. This is a policy setting,
            independent of end-user authentication. This default behavior is to
            allow login by active users, and reject login by inactive users.
    
            If the given user cannot log in, this method should raise a
            ``forms.ValidationError``.
    
            If the given user may log in, this method should return None.
            """
            if not user.is_active:
                raise forms.ValidationError(
                    self.error_messages['inactive'],
                    code='inactive',
                )
    
        def get_user_id(self):
            if self.user_cache:
                return self.user_cache.id
            return None
    
        def get_user(self):
            return self.user_cache
    View Code

      

       (3)AuthenticationForm:认证登录

    from django.shortcuts import render, Http404,redirect,HttpResponse
    from  website.models import  Video
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    from django.contrib.auth import authenticate, login
    from website.form import LoginForm
    from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
    # Create your views here.
    
    # 方法1:Django自带的AuthenticationForm登录表单,会帮助我们验证
    def index_login(request):
        context = {}
        if request.method == 'GET':
            form = AuthenticationForm
    
        if request.method == 'POST':
            form = AuthenticationForm(data=request.POST)        #验证
            if form.is_valid():                #用户存在,登录
                login(request, form.get_user())
                return redirect(to='list')
    
        context['form'] = form
        return render(request, 'register_login.html', context)
    

      

    # 方法2:form表单
    # def index_login(request):
    #     context = {}
    #     if request.method == 'GET':
    #         form = LoginForm
    #         print('11111111')
    #     if request.method == 'POST':
    #         form = LoginForm(request.POST)
    #         print(form)
    #         if form.is_valid():
    #             username = form.cleaned_data['username']   #取出数据
    #             password = form.cleaned_data['password']
    #             user = authenticate(username=username, password=password)  #authenticate函数
    #
    #             #验证用户对象  如果是真,就True
    #             if user:
    #                 login(request, user)
    #                 return redirect(to='list')
    #             else:
    #                 return HttpResponse('<h1>Not this User</h1>')
    #
    #     context['form'] = form
    #     return render(request, 'register_login.html', context)
    

      

      (4)UserCreationForm:注册用户

     

    from django.shortcuts import render, Http404,redirect,HttpResponse
    from  website.models import  Video
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    from django.contrib.auth import authenticate, login
    from website.form import LoginForm
    from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
    # Create your views here.
    
    def index_register(request):
        """注册"""
        context = {}
        if request.method == 'GET':
            form = UserCreationForm
        if request.method == 'POST':
            form = UserCreationForm(request.POST)
            if form.is_valid():
                form.save()   #表单验证没有问题(用户名占用,不合法字符),就保存
                return redirect(to='login')
        context['form'] = form
        return redner(request, 'register_login.html', context)
    

      

      (6)UserCreationForm 查看源码

     

    class UserCreationForm(forms.ModelForm):
        """
        A form that creates a user, with no privileges, from the given username and
        password.
        """
        error_messages = {
            'password_mismatch': _("The two password fields didn't match."),
        }
        password1 = forms.CharField(label=_("Password"),
            widget=forms.PasswordInput)
        password2 = forms.CharField(label=_("Password confirmation"),
            widget=forms.PasswordInput,
            help_text=_("Enter the same password as before, for verification."))
    
        class Meta:
            model = User
            fields = ("username",)
    
        def clean_password2(self):
            password1 = self.cleaned_data.get("password1")
            password2 = self.cleaned_data.get("password2")
            if password1 and password2 and password1 != password2:
                raise forms.ValidationError(
                    self.error_messages['password_mismatch'],
                    code='password_mismatch',
                )
            self.instance.username = self.cleaned_data.get('username')
            password_validation.validate_password(self.cleaned_data.get('password2'), self.instance)
            return password2
    
        def save(self, commit=True):
            user = super(UserCreationForm, self).save(commit=False)
            user.set_password(self.cleaned_data["password1"])
            if commit:
                user.save()
            return user
    View Code

      (8)view视图文件

    from django.shortcuts import render, Http404,redirect,HttpResponse
    from  website.models import  Video
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    from django.contrib.auth import authenticate, login
    from website.form import LoginForm
    from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
    # Create your views here.
    
    def index_register(request):
        """注册"""
        context = {}
        if request.method == 'GET':
            form = UserCreationForm
        if request.method == 'POST':
            form = UserCreationForm(request.POST)
            if form.is_valid():
                form.save()   #表单验证没有问题(用户名占用,不合法字符),就保存
                return redirect(to='login')
        context['form'] = form
        return reder(request, 'register_login.html', context)
    
    # 方法1:Django自带的AuthenticationForm登录表单,会帮助我们验证
    def index_login(request):
        context = {}
        if request.method == 'GET':
            form = AuthenticationForm
    
        if request.method == 'POST':
            form = AuthenticationForm(data=request.POST)        #验证
            if form.is_valid():                #用户存在,登录
                login(request, form.get_user())
                return redirect(to='list')
    
        context['form'] = form
        return render(request, 'register_login.html', context)
    
    # 方法2:form表单
    # def index_login(request):
    #     context = {}
    #     if request.method == 'GET':
    #         form = LoginForm
    #         print('11111111')
    #     if request.method == 'POST':
    #         form = LoginForm(request.POST)
    #         print(form)
    #         if form.is_valid():
    #             username = form.cleaned_data['username']   #取出数据
    #             password = form.cleaned_data['password']
    #             user = authenticate(username=username, password=password)  #authenticate函数
    #
    #             #验证用户对象  如果是真,就True
    #             if user:
    #                 login(request, user)
    #                 return redirect(to='list')
    #             else:
    #                 return HttpResponse('<h1>Not this User</h1>')
    #
    #     context['form'] = form
    #     return render(request, 'register_login.html', context)
    
    
    
    def listing(request, cate=None):  #cate可选默认参数
        context = {}
    
        if cate is None:
            video_list = Video.objects.all()
        if cate == 'editors':
            video_list = Video.objects.filter(editors_choice=True)
        else:
            video_list = Video.objects.all()
    
        page_rebot = Paginator(video_list, 9)  # 每页9个数据
        page_num = request.GET.get('page')
    
        try:
            video_list = page_rebot.page(page_num)  # get方法取哪一页
        except EmptyPage:
            video_list = page_rebot.page(page_rebot.num_pages)  # 999加载最后一页
            #raise Http404('EmptyPage')  #返回404错误
        except PageNotAnInteger:
            video_list = page_rebot.page(1)        # 432jds 加载第一页
    
        context['video_list'] = video_list
        listing_page = render(request, 'listing.html', context)
        return listing_page
    View Code

      (9)url地址

     

    • logout源码

    @deprecate_current_app
    def logout(request, next_page=None,
               template_name='registration/logged_out.html',
               redirect_field_name=REDIRECT_FIELD_NAME,
               extra_context=None):
        """
        Logs out the user and displays 'You are logged out' message.
        """
        auth_logout(request)
    
        if next_page is not None:
            next_page = resolve_url(next_page)
    
        if (redirect_field_name in request.POST or
                redirect_field_name in request.GET):
            next_page = request.POST.get(redirect_field_name,
                                         request.GET.get(redirect_field_name))
            # Security check -- don't allow redirection to a different host.
            if not is_safe_url(url=next_page, host=request.get_host()):
                next_page = request.path
    
        if next_page:
            # Redirect to this page until the session has been cleared.
            return HttpResponseRedirect(next_page)
    
        current_site = get_current_site(request)
        context = {
            'site': current_site,
            'site_name': current_site.name,
            'title': _('Logged out')
        }
        if extra_context is not None:
            context.update(extra_context)
    
        return TemplateResponse(request, template_name, context)
    View Code

      (10)T层:登出

     

     

     

     

    9.优化代码:显示错误信息

    •   register注册代码显示
    • register与login同用一个页面
                    <form class="ui form error" method="post">
    
                        {% if form.errors %}
                            <div class="ui error message">
                                {{ form.errors }}
                            </div>
    
                            {% for field in form  %}
                                <div class="{{ field.errors|yesno:'error, ' }} field">
                                    {{ field.label }}
                                    {{ field }}
                                </div>
                            {% endfor %}
    
                        {% else %}
                            {% for field in form  %}
                                <div class="field">
                                    {{ field.label }}
                                    {{ field }}
                                </div>
                            {% endfor %}
    
                        {% endif %}
    
                        {% csrf_token %}
    
                        <button class="ui inverted red circular right floated button" type="submit">Done</button>
                    </form>
    

      

     register_login.html 代码

     

    <!DOCTYPE html>
    {% load staticfiles %}
    
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
            <link rel="stylesheet" href="{% static 'css/semantic.css' %}" media="screen" title="no title" charset="utf-8">
            <link rel="stylesheet" href="{% static 'css/list_custom.css' %}"  media="screen" title="no title" charset="utf-8">
            <link href="https://fonts.googleapis.com/css?family=Oswald|Raleway" rel="stylesheet">
            <style type="text/css">
                body {
                    background: url({% static 'images/super_blur_back2.jpg' %});
                    background-size: cover;
                }
    
                .ui.grid.divided.segment.container{
                    min-height: 400px;
                    600px !important;
                    border:rgba(255, 0, 0, 0);
                    position: absolute;
                    left: 50%;
                    top:40%;
                    transform: translate(-50%,-50%);
                }
    
                .five.wide.column {
                    background: url({% static 'images/red_regi.jpg'  %});
                    background-size: cover;
                    background-position: 60% 0%;
                }
    
                form {
                    margin-top: 60px;
                }
                h1,h3,h4{
                    font-family: 'Play', sans-serif !important;
    
                }
            </style>
    
        </head>
        <body>
            <div class="ui grid divided segment container">
                <div class="five wide  column">
    
                    <h4 class="ui inverted header">
    
                        <i class="angle left  icon"></i>
                    </h4>
    
                    <h1 class="ui inverted center aligned header" style="font-size: 40px;margin-top:55px">
                        <p class="sub header">
                            Welcome to
                        </p>
                        10MINs
                    </h1>
    
                </div>
    
                <div class="eleven wide column">
                    <h4 class="ui inverted right aligned header">
                        <a href="#" style="color:#ff695e;">or LOGIN</a>
                    </h4>
    
                    <form class="ui form error" method="post">
    
                        {% if form.errors %}
                            <div class="ui error message">
                                {{ form.errors }}
                            </div>
    
                            {% for field in form  %}
                                <div class="{{ field.errors|yesno:'error, ' }} field">
                                    {{ field.label }}
                                    {{ field }}
                                </div>
                            {% endfor %}
    
                        {% else %}
                            {% for field in form  %}
                                <div class="field">
                                    {{ field.label }}
                                    {{ field }}
                                </div>
                            {% endfor %}
    
                        {% endif %}
    
                        {% csrf_token %}
    
                        <button class="ui inverted red circular right floated button" type="submit">Done</button>
                    </form>
                </div>
            </div>
        </body>
    </html>
    View Code
  • 相关阅读:
    js--未来元素
    Nginx 浏览器打开是下载状态
    JS对象的深拷贝
    微信小程序--扫描二维码
    js--call( )/apply()/bind()--应用
    数学书籍
    【活动】你有创意我有奖!摹客X飞书2020产品设计大赛邀你来战
    APP设计实例解析,深色模式为什么突然就火了?
    焦虑求职季又至:2020UI设计师作品集如何准备?
    QQ音乐 vs 网易云音乐,用户体验哪家强?
  • 原文地址:https://www.cnblogs.com/venicid/p/8109132.html
Copyright © 2011-2022 走看看