• 关于Django登录功能实现的几种方案


    方案一,采用django自带的login

    优缺点:缺少css样式,适合敏捷开发,对于前端样式上需要花一些功夫;好处就是错误提示不需要我们刻意去实现

    参考图片:

    image

    image

    具体实现:

    urls.py:

    from django.contrib.auth import views as auth_views
    from account.forms import MyAuthenticationForm
    urlpatterns = [
        path('login/', auth_views.LoginView.as_view(
            template_name="account/login.html", authentication_form=MyAuthenticationForm),name='login'),       #登录用
        path('logout/', auth_views.LogoutView.as_view(next_page="/"), name='logout'),  #登出用
    
    

    forms.py:

    from django.contrib.auth.forms import AuthenticationForm,
    
    from captcha.fields import CaptchaField,CaptchaTextInput   # 图片验证码,可以不加
    
    # 图片验证码,可以不加
    class CustomCaptchaTextInput(CaptchaTextInput): 
        template_name = 'custom_captcha.html'
    
    class MyAuthenticationForm(AuthenticationForm):
        captcha = CaptchaField(label="验证码", required=True,error_messages={'invalid':'验证码错误'},
                               widget=CustomCaptchaTextInput)  # 这个是实现验证码,可以不加
        
        def __init__(self, *args, **kwargs):
            super(MyAuthenticationForm, self).__init__(*args, **kwargs)
            self.fields['username'].widget.attrs['placeholder'] = u'输入账号'
            self.fields['password'].widget.attrs['placeholder'] = u'输入密码'
            self.fields['captcha'].widget.attrs['placeholder'] = u'验证码'   #可以不加
    

    login.html:

    <style>
        .form-inline label {
             20%;
            display: block;
            text-align: left;
        }
    
        .form-inline input {
             80%;
        }
    
        .errorlist {
            color: red;
        }
        #id_captcha_1 {
             150px;
            margin-right: 10px;
        }
    </style>
    <form class="form-account" method="post">
        {% csrf_token %}
        <h2 class="form-account-heading text-center">登录平台</h2>
        {{ form.non_field_errors }}
        {% for field in form %}
        <div class="form-group form-inline{% if field.name != 'captcha' %} d-flex justify-content-between{% endif %}">
            {{ field.label_tag }} {{ field }}
            {% if field.help_text %}
            <p class="help">{{ field.help_text|safe }}</p>
            {% endif %}
            <p>{{ field.errors }}</p>
        </div>
        {% endfor %}
        <button class="btn btn-lg btn-primary btn-block" type="submit">登录</button>
    </form>
    

    方案二,自定义View,自定义Form

    优缺点:虽然自定义程度较高,但是更符合我们的预期,可控的前端样式;不需要根据表单渲染出的id再去写css样式

    参考图片:

    image

    urls.py:

    from accounts import views
    from django.contrib.auth.views import LogoutView
    
    
    app_name = 'account'
    
    urlpatterns = [
        path('login/', views.AccountLoginView.as_view(), name='login'),
        path('logout/', LogoutView.as_view(next_page="/"), name='logout'),
    ]
    

    views.py:

    from django.views import View
    
    class AccountLoginView(View):
        def post(self, request):
            f = forms.LoginForm(request.POST)
            if f.is_valid():  # 通过form校验数据格式
                user_obj = authenticate(username=f.cleaned_data["username"], password=f.cleaned_data["password"])  # 认证提交的表单是否满足数据库记录
                if user_obj:
                    login(request, user_obj)  # 登录当前用户
                    next_url = self.get_redirct_url(user_obj)  # 这里通过鉴定用户角色,返回相应的url
                    if next_url:
                        messages.success(request, "欢迎登录")
                        return redirect(next_url)
    
            messages.success(request, '登录失败,错误的账号密码')
            return redirect('home')
        
        def get_redirct_url(self, user):
            # 判断用户属组,重定向至相应的页面
            client_group = user.groups.filter(name="client")
            doctor_group = user.groups.filter(name="doctor")
            if client_group:
                return reverse("client:home")  #  /client/index/
            elif doctor_group:
                return reverse("doctor:home")
            elif user.is_superuser:
                return reverse("admin:index")
    

    forms.py

    from django import forms
    
    class CustomCharField(forms.CharField):
        # 继承CharField并为其添加class使其带有bootstrap样式
        def __init__(self, *, max_value=None, min_value=None, **kwargs):
            super().__init__(**kwargs)
    
    
        def widget_attrs(self, widget):
            attrs = super().widget_attrs(widget)
            attrs["class"] = 'form-control form-control-sm bg-light'
            attrs["placeholder"] = self.label
            return attrs
    
    
    class LoginForm(forms.Form):
        username = CustomCharField(
            label="Username",
            widget=forms.TextInput(
                attrs={"id": "login_username", "autocomplete": "new-username"}))
    
        password = CustomCharField(
            label="Password",
            strip=False,
            widget=forms.PasswordInput(attrs={'autocomplete': 'current-password',"id": "login_password"}),
        )
    
    

    home.html

    <div class="modal-body">
        <form class="form-account" method="post" action="{% url 'account:login' %}">
            <div class="row row-cols-2 row-cols-md-2">
                {% csrf_token %}
                {{ form.non_field_errors }}
                {% for field in login_form %}
                <div class="form-group col-5">
                    {{ field.label_tag }} {{ field }}
                    {% if field.help_text %}
                    <small class="form-text text-muted text-right">{{ field.help_text|safe }}</small>
                    {% endif %}
                    {% if field.errors %}
                    <p>{{ field.errors }}</p>
                    {% endif %}
                </div>
                {% endfor %}
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                <button type="submit" class="btn btn-primary">Login</button>
            </div>
        </form>
    </div>
    
    

    方案三,自定义view,form定或不定都行,主要是页面渲染采用第三方包

    优缺点:新引入的包不仅省了方案二的自定义FIeld,还带了其他功能,这里只写form渲染。缺点就是为了渲染字段而引入一个包。

    参考图片:

    ...参考方案二

    pip:

    # 两个包都可以:django-bootstrap、django-crispy-forms
    pip install django-bootstrap
    # 或
    pip install django-crispy-forms
    
    # 参考用法:github.com 搜索
    

    forms.py \ views.py \ urls.py参考方案二

    index.html:

    {% load bootstrap %}
    <div class="modal-body">
        <form class="form-account" method="post" action="{% url 'account:login' %}">
            <div class="row row-cols-2 row-cols-md-2">
                {% csrf_token %}
                {{ form|bootstrap }}
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                <button type="submit" class="btn btn-primary">Login</button>
            </div>
        </form>
    </div>
    
    {# 或者 #}
    
    {% load crispy %}
    <div class="modal-body">
        <form class="form-account" method="post" action="{% url 'account:login' %}">
            <div class="row row-cols-2 row-cols-md-2">
                {% csrf_token %}
                {{ form|crispy }}
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                <button type="submit" class="btn btn-primary">Login</button>
            </div>
        </form>
    </div>
    
  • 相关阅读:
    SSM学习(三)--集成spring mvc
    SSM学习(二)mybatis和spring的集成
    SSM学习(一)搭建基础框架
    (转)Maven依赖的jar包下载不了、jar更新不了的解决办法
    maven安装配置及使用maven创建一个web项目
    JavaWeb -- Servlet+JSP+JavaBean(MVC)模式
    JavaWeb -- JSP+JavaBean模式
    JavaWeb -- Jsp 和 JavaBean
    JavaScript -- 练习 window 流氓广告
    上网代理
  • 原文地址:https://www.cnblogs.com/lisicn/p/15767168.html
Copyright © 2020-2023  润新知