乐趣区

关于python:Django之用户管理系统CBV全新升级5

工夫过的真快,又靠近 4 个月没更新文章了,不是我闲着,家里事件是真多,工夫都给了溜娃还是溜娃,残余点工夫就学习 Django 的常识,为了打磨好这一篇文章,可费了九牛二虎之力,实现该篇文章。

为了各位读者有较好的 UI 视觉、有能源去学习和摸索,前端可投入不少工夫。毕竟作为一名 网工 ,去搞前端,那还真不是一件容易的事件,你想,Django 这个后端常识体系曾经够学一阵一阵子的了。

前端有啥学习?HTML、javascrip、jQuery、ajAX、Vue…

后端有啥学习?Django 就够了 …

后方高能,请看如下效果图 …

1.0 成果展现

阐明:提前贴出这些图,心愿各位看了有能源去学习。尽管 django 有自带一套用户零碎,然而人的审美总是要有的哈,又能够晋升下本人的代码程度.

  • 用户列表展现

  • 新增用户
  • 更新用户
  • 删除用户

1.1 根底配置

阐明:有一些共性的货色,我就提前在这个章节写进去。

  • settings.py 配置
    文件门路:mysite/settings.py

    static 文件夹门路:用于寄存前端的一些 cssjsicon 等文件。

    AUTH_USER_MODEL:重写内置的用户治理。

    DATABASES:应用的是 mysql 数据库,始终用的这个。

    INSTALLED_APPS:新建和注册 app,就不多讲了,请看之前的文章。

# mysite/settings.py

INSTALLED_APPS = [
    # 新建的 app, 注册一下
    'users',  
]

# 定义寄存 js/cs/img 的文件门路
STATIC_URL = '/static/'
STATICFILES_DIRS = ((BASE_DIR / 'static'),
)
# 全局申明,应用 UserProfile
# 默认是: AUTH_USER_MODEL = 'auth.User'
AUTH_USER_MODEL = 'users.UserProfile'

# 数据库 mysql 参数配置, 内置有 sqlite。DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_db',
        'HOST': '192.168.8.130',
        'USER': '< 数据库用户名 >',
        'PASSWORD': '< 数据库明码 >,'PORT': 3306,
    }
}
  • 母版配置
    文件门路:mysite/templates/base1.html

    templates 目录下新建 base1.html 文件,作为 母版, 代码如下所示。

    阐明: 母版寄存 根本 cssjs 款式, 这样子页面就不必独自加载这些了,切记不要把所有的 js 或 css 放在一个 html 内,防止导致页面加载慢,按需页面加载即可。

<!-- mysite/templates/base1.html -->

<!DOCTYPE html>
{% load  static %}
<html lang="en">
    
<head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta name="description" content="">
        <meta name="author" content="">
        <!-- 页面标签 -->
        <title>
            {% block title %}自动化运维平台{% endblock %}
        </title>

        <!-- 加载 CSS 款式 -->
        <!-- Bootstrap core CSS -->
        <link href="{% static"css/bootstrap.min.css"%}" rel="stylesheet">
        <link href="{% static"css/bootstrap-reset.css"%}" rel="stylesheet">

        <!--Animation css-->
        <link href="{% static"css/animate.css"%}" rel="stylesheet">

        <!--Icon-fonts css-->
        <link href="{% static"assets/font-awesome/css/font-awesome.css"%}" rel="stylesheet" />
        <link href="{% static"assets/ionicon/css/ionicons.min.css"%}" rel="stylesheet" />

        <!--Morris Chart CSS -->
        <link rel="stylesheet" href="{% static"assets/morris/morris.css"%}">

        <!-- Custom styles for this template -->
        <link href="{% static"css/style.css"%}" rel="stylesheet">
        <link href="{% static"css/helper.css"%}" rel="stylesheet">

        <!-- Plugin Css-->
        <link rel="stylesheet" href="{% static"assets/magnific-popup/magnific-popup.css"%}" />
        <link rel="stylesheet" href="{% static"assets/jquery-datatables-editable/datatables.css"%}" />

        <!-- Custom styles for this template -->
        <link rel="stylesheet" href="{% static"css/style.css"%}">
        <link rel="stylesheet" href="{% static"css/helper.css"%}">

        {% block css %}{% endblock %}
</head>

    <body>
        <!-- Aside Start-->
        <aside class="left-panel">
            <!-- brand -->
            <div class="logo">
                <a href="{% url'index'%}" class="logo-expanded">
                    <i class="ion-social-buffer"></i>
                    <span class="nav-label"> 自动化运维平台 </span>
                </a>
            </div><!-- / brand -->

            <!-- Navbar Start 导航栏 -->
            <nav class="navigation">
                <ul class="list-unstyled">
                    <li class="active"><a href="#"><i class="ion-home"></i> <span class="nav-label"> 仪表盘 </span></a></li>
                    <li class="has-submenu"><a href="#"><i class="ion-android-social-user"></i> <span class="nav-label"> 用户权限治理 </span></a>
                <ul class="list-unstyled">
                    <li class="users"><a href="{% url'users:userlist'%}"> 用户治理 </a></li>
                    <li class="roles"><a href="#"> 角色治理 </a></li>
                    <li class="permissions"><a href="#"> 权限治理 </a></li>
                </ul>
                    </li>
                </ul>
            </nav><!-- Navbar Ends -->
        </aside><!-- Aside Ends-->

        <!--Main Content Start -->
        <section class="content">
            
            <!-- Header -->
            <header class="top-head container-fluid">
                <!-- 左上角膨胀 导航栏 -->
                <button type="button" class="navbar-toggle pull-left">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>

                <nav class="navbar-default" role="navigation">
                    <!-- Right navbar -->
                    <ul class="nav navbar-nav navbar-right top-menu top-right-menu">
                        <!-- user login dropdown start-->
                        <li class="dropdown text-center">
                            <a data-toggle="dropdown" class="dropdown-toggle" href="#">
                                <img alt=""src="{% static "img/avatar-2.jpg" %}"class="img-circle profile-img thumb-sm">
                                <span class="username"> admin </span> <span class="caret"></span>
                            </a>
                            <ul class="dropdown-menu pro-menu fadeInUp animated" tabindex="5003" style="overflow: hidden; outline: none;">
                                <li><a href="#"><i class="fa fa-edit"></i> 批改明码 </a></li>
                                <li><a href="#"><i class="fa fa-sign-out"></i> 退出 </a></li>
                            </ul>
                        </li>
                        <!-- user login dropdown end -->       
                    </ul>
                    <!-- End right navbar -->
                </nav>
                
            </header>
            <!-- Header Ends -->
            <!-- 以上就是每一个页面共用的局部,即母版 -->

            <!-- Page Content Start -->
            <!-- ================== -->
            <!-- 以下就是每一个页面自定义内容的局部 -->
            <div class="wraper container-fluid">
                <div class="page-title"> 
                    <h3 class="title"> {% block page-title %} {% endblock %} </h3>
                </div>

                {% block page-content %} {% endblock %}

            </div>
            <!-- Page Content Ends -->
            <!-- ================== -->

            <!-- 页脚 Footer Start -->
            <footer class="footer">
                2021©自动化运维平台
            </footer>
            <!-- 页脚 Footer Ends -->

        </section>
        <!-- Main Content Ends -->
        <script src="{% static'js/jquery.js'%}"></script>
        <script src="{% static'js/bootstrap.min.js'%}"></script>
        <script src="{% static'js/wow.min.js'%}"></script>
        <script src="{% static'js/pace.min.js'%}"></script>
        <!-- 管制菜单栏点击显示子菜单 -->
        <script src="{% static'js/jquery.app.js'%}"></script>
        <!-- 子菜单点击时,不膨胀 -->
        <script src="{% static'js/jquery.nicescroll.js'%}" ></script>

        {% block js %}{% endblock %}

    </body>
</html>
  • model 配置
    文件门路: mysite/users/models.py

    继承内置用户零碎 AbstractUser, 内置有usernamepasswordemailis_active 等字段,我在此基础上减少了cn_namephonesex, 3 个字段属性。

    # mysite/users/models.py
    #!/usr/bin/env python3
    #-*- coding:UTF-8 -*-
    
    from django.db import models
    from django.contrib.auth.models import AbstractUser
    
    class Userprofile(AbstractUser):
        SEX_CHOICE = ((0, '男'),
            (1, '女'),
        )
        cn_name = models.CharField('中文名', max_length=128)
        phone = models.CharField('手机', max_length=11, null=True, blank=True)
        sex = models.IntegerField(choices=SEX_CHOICE, null=True, blank=True)
    
        class Meta:
            verbose_name = '用户信息'
    
        def __str__(self):
            return self.username

    舒适提醒:model 编写好后,各位记得python manage.py makemigrations userspython manage.py migrate users

  • 路由 url 配置
    文件门路:mysite/urls.py

    主路由 urls:

    # mysite/urls.py
    
    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [path('admin/', admin.site.urls),
        path('user/', include('users.urls'))  # 新建
    ]

    子路由 urls(app 为 users):

    # mysite/users/urls.py
    
    from django.urls import path, re_path
    from .views import *
    
    app_name = 'users'
    urlpatterns = [
        # 用户查看
        path('userlist/', UserListView.as_view(), name='userlist'),
        # 用户减少
        path('useradd/', UserAddView.as_view(), name='useradd'),
        # 用户编辑
        re_path('useredit/(?P<pk>[0-9]+)?/', UserEditView.as_view(), name='useredit'),
        # 用户删除
        re_path('userdel/(?P<pk>[0-9]+)?/', UserDelView.as_view(), name='userdel'),
        ]
  • 分页
    文件门路:mysite/templates/_paginator.html

    成果是这样子的:


    templates 目录下创立 _paginator.html,写入如下代码:
    阐明:这个分页文件会在 userlist.html 被调用,这个模板是他人写好的,拿来用即可.

    # mysite/templates/_paginator.html
    
    <ul class="pagination m-b-5" style="float: right">
        {% if page_obj.has_previous %}
            <li><a href="?page=1"> 首页 </a></li>
            <li><a href="?{{page_obj.previous_page_number.querystring}}" aria-label="上一页"> 上一页 </a></li>
        {% else %}
            <li><a class="disabled" href="?page=1"> 首页 </a></li>
            <li><a class="disabled"> 上一页 </a></li>
        {% endif %}
        {% for page in page_obj.pages %}
             {% if page %}
                {% ifequal page page_obj.number %}
                    <li class="active"><a class="">{{page}}</a></li>
                {% else %}
                    <li><a class=""href="?{{page.querystring}}">{{page}}</a></li>
                {% endifequal %}
            {% else %}
                 <li><a class=""href="javascript:void(0)">...</a></li>
            {% endif %}
        {% endfor %}
        {% if page_obj.has_next %}
            <li><a class=""href="?{{page_obj.next_page_number.querystring}}"> 下一页 </a></li>
            <li><a class=""href="?page={{page_obj.paginator.num_pages}}"> 尾页 </a></li>
        {% else %}
            <li><a class="disabled"> 下一页 </a></li>
            <li><a class="disabled"> 尾页 </a></li>
        {% endif %}
    </ul>

1.2 用户增加

阐明:用户增加的表单应用 forms 的 ModelForm,能够依赖 model, 视图则应用 generic(通用视图) 的CreateView.

  • 创立 form.py 文件

    #!/usr/bin/env python3
    #-*- coding:UTF-8 -*-
    
    from django import forms
    from django.contrib.auth import get_user_model
    import re
    
    class UserModelForm(forms.ModelForm):
        # 新增确认明码字段,用于两次明码作比拟
        # 该字段不必写入数据库
        confirm_password = forms.CharField(required=True)
    
        class Meta:
            # 与 model 建设了依赖关系,即依照 model 中的字段类型验证
            model = User
            # 依据 model 定义的类型,验证列的属性
            fields = ('username', 'cn_name', 'password', 'sex', 'phone')
    
        def clean_phone(self):
            # clean_字段名,该办法用于验证字段,自定义条件
            phone = self.cleaned_data['phone']
            if phone:
                phone_re = re.match("^1[35789][0-9]{9}$", phone)
                # print(phone_re)
                if phone_re:
                    return phone
                else:
                    raise forms.ValidationError("手机号码非法")
            else:
                # ValidationError 自定义表单谬误
                raise forms.ValidationError("这个字段是必填项")
    
        def clean_confirm_password(self):
            """用于比拟两次输出的明码"""
            password = self.cleaned_data.get('password')
            confirm_password = self.cleaned_data.get('confirm_password')
            if password != confirm_password:
                raise forms.ValidationError('两次明码不统一!')
            # return confirm_password

    阐明:设计成表单,须要独自创立一个 form.py, 名字自定义,def clean_字段名 用于判断表单的字段是否合乎设定的要求。

  • 视图配置
    文件门路:mysite/users/views.py

    # mysite/users/views.py
    
    from django.views.generic import CreateView
    from django.contrib.messages.views import SuccessMessageMixin
    from django.contrib.auth import get_user_model
    from .form import UserModelForm
    
    User = get_user_model()
    
    class UserAddView(SuccessMessageMixin, CreateView):
        """新增用户"""
        template_name = 'users/form.html'
        model = User
        form_class = UserModelForm
        success_message = '%(username)s 用户增加胜利!'
    
        def get_success_url(self):
            # print(self.request.POST)
            if "_addanother" in self.request.POST:
                return reverse('users:useradd')
            return reverse('users:userlist')
    
        def form_valid(self, form):
            """
            form.cleaned_data:获取表单所有数据
            from.instance:一个用户对象(是一个类)
            """password = form.cleaned_data['password']
            form.instance.password = make_password(password)
            # print(form.cleaned_data)
            # print(make_password(password))
            # print(form.instance)
            return super(UserAddView, self).form_valid(form)
    
        def form_invalid(self, form):
            """form_invalid 办法能够不必写,用于 print 表单报错."""
            # print('form_invalid', form.cleaned_data)
            # print(form.errors.as_json())
            return super(UserAddView, self).form_invalid(form)

    参数解读:

    • get_success_url:如果表单失常,return 重定向到定义的 url。
    • form_valid:如果表单失常,进入该函数,并通过 make_password 办法生成随机的密文,默认会通过 form.save() 写入数据库中。
    • form_invalid:如果表单异样,进入该函数(仅用于演示,可不写).
  • 模板配置
    文件门路:mysite/users/templates/form.html

    阐明:用户新增和用户批改应用的是同一个模板,外面通过 if 条件进行辨别.

    <!-- mysite/users/templates/form.html -->
    
    {% extends 'base1.html' %}
    
    {% load static %}
    
    {% block title %}
        {% if object %}
            用户更新
        {% else %}
            用户增加
        {% endif %}
    {% endblock %}
    
    {% block page-title %}
        {% if object %}
            用户更新
        {% else %}
            用户增加
        {% endif %}
    {% endblock %}
    
    {% block page-content %}
        <!-- Form-validation -->
    <div class="row">
        <div class="col-sm-12">
            <div class="panel panel-default">
    
                <div class="panel-heading"><h3 class="panel-title">{% if object %}请更新一个用户 {% else %} 请增加一个用户{% endif %}</h3></div>
                <div class="panel-body">
    
                    {% if form %}
                            <div class="alert  alert-dismissable">
                                <button type="button" class="close" data-dismiss="alert" aria-hidden="true">x</button>
                                <p style="color: red"> {{form.errors}} </p>
                            </div>
                    {% endif %}
    
                    <div class="form">
                        <form class="cmxform form-horizontal tasi-form" id="signupForm" method="post" action=""novalidate="novalidate">
                            <div class="form-group">
                                <label for="username" class="control-label col-lg-2"> 用户名 *</label>
                                <div class="col-lg-10">
                                    <input class="form-control" name="username" value="{% if object %}{{object.username}}{% endif %}" type="text">
                                </div>
                            </div>
    
    
                            <div class="form-group">
                                <label for="cn_name" class="control-label col-lg-2"> 中文名 *</label>
                                <div class="col-lg-10">
                                    <input class="form-control" name="cn_name" value="{% if object %}{{object.cn_name}}{% endif %}" type="text">
                                </div>
                            </div>
    
                            <div class="form-group">
                                <label for="password" class="control-label col-lg-2"> 明码 *</label>
                                <div class="col-lg-10">
                                    <input class="form-control" name="password" value=""type="password">
                                </div>
                            </div>
    
                            <div class="form-group">
                                <label for="confirm_password" class="control-label col-lg-2"> 再次输出明码 *</label>
                                <div class="col-lg-10">
                                    <input class="form-control" name="confirm_password" value=""type="password">
                                </div>
                            </div>
    
                            <div class="form-group">
                                <label for="name" class="control-label col-lg-2"> 手机号 *</label>
                                <div class="col-lg-10">
                                    <input class="form-control" name="phone" value="{% if object %} {{object.phone}} {% endif %}" type="text">
                                </div>
                            </div>
    
                            <div class="form-group">
                                <label for="level" class="control-label col-lg-2"> 性别 *</label>
                                <div class="col-lg-10">
                                    <div class="radio-inline">
                                        <label class="cr-styled" >
                                            <input type="radio"  name="sex" value="0" {% if object %}{% if object.sex == 0 %}checked{% endif %}{% endif %} checked>
                                            <i class="fa"></i>
                                            男
                                        </label>
                                    </div>
                                    <div class="radio-inline">
                                        <label class="cr-styled">
                                            <input type="radio"  name="sex" value="1" {% if object %}{% if object.sex == 1 %}checked{% endif %}{% endif %}>
                                            <i class="fa"></i>
                                            女
                                        </label>
                                    </div>
                                </div>
                            </div>
    
                            <div class="form-group">
                                <div class="col-lg-offset-2 col-lg-10">
                                     <button class="btn btn-success" type="submit"> 确定 </button>
                                     {% if object %}
                                         <button type="submit" name='_savedit' class="btn btn-purple"> 保留并持续编辑 </button>
                                     {% endif %}
                                     <button type="submit" name='_addanother' class="btn btn-purple" > 保留并增加另一个 </button>
                                     <button type="button" class="btn btn-default" onclick="location.href='{% url 'users:userlist' %}'"> 勾销 </button>
                                </div>
                            </div>
                        </form>
                    </div> <!-- .form -->
    
                </div> <!-- panel-body -->
            </div> <!-- panel -->
        </div> <!-- col -->
    
    </div> <!-- End row -->
    {% endblock %}

    阐明:用户更新页面通过 if 判断 object 为 true,否则就是用户增加页面了

    • 效果图

1.3 用户查看

  • 视图配置

    from django.views.generic import ListView
    from pure_pagination.mixins import PaginationMixin
    from django.contrib.auth import get_user_model
    
    User = get_user_model()
    
    class IsActiveView(View):
        def post(self, request, **kwargs):
            pk = QueryDict(self.request.body).get('pk')
            value =int(QueryDict(self.request.body).get('value'))
            try:
                user = User.objects.filter(id=pk)
                if pk and value == 1:
                    user.update(is_active=1)
                    res = {'code': 0, 'result': '用户激活胜利!'}
                elif pk and value == 0:
                    user.update(is_active=0)
                    res = {'code': 0, 'result': '用户禁用胜利!'}
                else:
                    res = {'code': 1, 'result': '用户禁用或激活失败!'}
            except:
                res = {'code': 1, 'result': '用户禁用或激活失败!'}
    
            return JsonResponse(res, safe=True)
        
        
    class UserListView(PaginationMixin, ListView):
        """查看用户"""
        template_name = 'users/userlist.html'
        model = User
        context_object_name = 'users'
        paginate_by = 10
        keyword = ''def get_queryset(self):""" 数据过滤, return 过滤后的数据 """
            # 获取所有数据
            queryset = super(UserListView, self).get_queryset()
            # print(queryset)
            # 获取搜寻框的关键字
            self.keyword = self.request.GET.get('keyword', '')
            if self.keyword:
                if self.keyword == '男':
                    queryset = queryset.filter(sex=0)
                    # print(queryset)
                elif self.keyword == '女':
                    queryset = queryset.filter(sex=1)
                else:
                    queryset = queryset.filter(Q(username__icontains=self.keyword)|
                                               Q(cn_name__icontains=self.keyword)|
                                               Q(is_superuser__icontains=self.keyword)|
                                               Q(phone__icontains=self.keyword)|
                                               Q(is_active__icontains=self.keyword))
            else:
                pass
            return queryset
    
        def get_context_data(self, **kwargs):
            """上下文治理,用于传递给前端渲染的数据"""
            context = super(UserListView, self).get_context_data(**kwargs)
            # print(context)
            context['keyword'] = self.keyword
            return context

    参数解读:

    • is_active:缺省为 true,is_active=1,is_active= 0 示意未激活
    • template_name:指定前端渲染的模板(html 文件);
    • model:指定模型;
    • context_object_name:自定义上下文对象名称(传递给前端),缺省 object_list。
    • paginate_by:分页,每一页 10 条数据;
    • get_queryset:该办法继承父类获取所有数据,并通过 filter + Q 过滤数据, 还能够跟 order_by() 进行排序(升序 / 降序)。
    • Q:Q 对象提供更简单的查问,如通过 &| 操作符和括号分组,本文应用或关系。
    • get_context_data:该办法用于传给前端渲染的数据,keyword为传给前端搜寻框内显示用的。
  • 模板配置

    {% extends 'base1.html' %}
    {% load static %}
    
    {% block title %}
        用户列表
    {% endblock %}
    
    {% block page-title %}
        用户列表
    {% endblock %}
    
    
    {% block css %}
        <!-- sweet alerts -->
        <link rel="stylesheet" href="{% static"assets/sweet-alert/sweetalert2.min.css"%}">
        <link rel="stylesheet" href="{% static"assets/sweet-alert/sweetalert2.css"%}">
    
    {% endblock %}
    
    {% block page-content %}
    <div class="row">
    
        <div class="panel">
            <div class="panel-body">
                <!-- 增加及搜寻行 start-->
                <div class="row">
                    <!-- 增加按钮 -->
                    <div class="col-sm-6">
                        <div class="m-b-30">
                            <a href="{% url'users:useradd'%}" type="button" class="btn btn-primary waves-effect waves-light"> 增加用户 <i class="fa fa-plus"></i></a>
                        </div>
                    </div> <!-- 增加按钮 ends-->
    
                    <!-- 搜寻 -->
                    <div class="col-md-3" style="float: right">
                        <form class="form-horizontal" role="form">
                            <div class="input-group">
                                <input type="text"  name="keyword" class="form-control"  value="{{keyword|default_if_none:''}}"placeholder=" 请输出查问的关键字 ">
                                <span class="input-group-btn">
                                    <button type="submit" class="btn btn-effect-ripple btn-primary"> 搜寻 </button>
                                </span>
                            </div>
                        </form>
                    </div><!-- 搜寻 ends-->
    
                </div><!-- 增加及搜寻行 ends-->
    
                <!-- 表格 start-->
                <table class="table table-bordered table-striped">
                    <thead>
                        <tr>
                            <th>UID</th>
                            <th> 用户名 </th>
                            <th> 管理员 </th>
                            <th> 中文名 </th>
                            <th> 手机 </th>
                            <th> 性别 </th>
                            <th> 用户状态 </th>
                            <th> 上次登陆工夫 </th>
                            <th> 操作 </th>
                        </tr>
                    </thead>
    
                    <tbody>
                    {% for user in users %}
                    <tr class="gradeA">
                        <td>{{user.id}}</td>
                        <td>{{user.username}}</td>
                        <td>{% if user.is_superuser == 1 %}超级管理员 {% else %} 普通用户 {% endif %}</td>
                        <td>{{user.cn_name}}</td>
                        <td>{{user.phone}}</td>
                        <td>{{user.get_sex_display}}</td>
                        <td>
                            {% if user.is_active == 1 %}
                                <button type="button" class="btn btn-primary btn-xs"> 失常 </button> |
                                <button type="button" id="active" acitve_id="{{user.id}}" value=0 class="btn btn-danger btn-xs"><i class="fa fa-ban fa-lg"></i> 禁用 </button>
                            {% elif user.is_active == 0 %}
                                <button type="button" class="btn btn-warning btn-xs"> 离线 </button> |
                                <button type="button" id="active" acitve_id="{{user.id}}"value=1 class="btn btn-success btn-xs"><i class="fa fa-check-circle fa-lg"></i> 激活 </button>
                            {% else %}
                                未知
                            {% endif %}
                        </td>
                        <td>{% if user.last_login == None %}未登录{% else %} {{user.last_login}} {% endif %}</td>
                        <td class="actions">
                        <a href="{% url'users:useredit'user.id %}" class="btn btn-primary btn-xs"> 编辑 </a>
                        <a id="delbtn" userid="{{user.id}}" class="btn btn-danger btn-xs"> 删除 </a>
                    </tr>
                    {% endfor %}
                    </tbody>
                </table><!-- 表格 ends-->
            </div> <!-- panel-body ends-->
    
    
            <!-- 分页 start-->
            <div class="row">
                <div class="col-md-4">
                   <p style="margin-top: 10px"> 显示 [{{page_obj.paginator.count}}] 条数据中的 第 [{{page_obj.start_index}}] 至 [{{page_obj.end_index}}] 的数据 </p>
                </div>
                <div class="col-md-8">
                     {% if page_obj.paginator.num_pages > 1 %}
                        {% include '_paginator.html' %}
                     {% endif %}
                </div>
            </div> <!-- 分页 ends-->
    
        </div> <!-- end Panel -->
    
    </div> <!-- End row -->
    
    {% endblock %}
    
    {% block js %}
        <script src="{% static"js/jquery-3.6.0.js"%}"></script>
        <script src="{% static"assets/sweet-alert/sweetalert2.min.js"%}"></script>
        <script src="{% static"assets/sweet-alert/sweetalert2.all.min.js"%}"></script>
        <script src="{% static"assets/sweet-alert/sweetalert2.all.js"%}"></script>
        <script src="{% static"assets/sweet-alert/sweetalert2.js"%}"></script>
    
        <script>
            // 编辑删除按钮
            $("tbody").on("click","#delbtn", function () {
                // 定义变量
                var uid = $(this).attr('userid')
                var url = "/user/userdel/" + uid + '/'
                Swal.fire({
                    title: "确定删除该用户?",
                    text: "删除后可就无奈复原了。",
                    icon: "warning",
                    showCancelButton: true,
                    confirmButtonText: "是的,我要删除!",
                    cancelButtonText: "勾销",
                    cancelButtonColor: '#d33',
                    confirmButtonColor: '#3085d6',
                }).then((result) => {if (result.isConfirmed) {
                        // ajax 语法
                        $.ajax({
                            type: "post",
                            url: url,
                            success: function (res) {console.log(res)
                                if (res.code == 0) {
                                    Swal.fire({
                                        title: "删除胜利!",
                                        text: "该用户曾经删除了.",
                                        icon: "success",
                                        timer: 3000  // 单位是毫秒
                                    });
                                    setTimeout(function () {window.location.reload();
                                    }, 3000)  // 单位是毫秒,重刷新页面
                                }
                                else {Swal.fire("OMG...", "出错拉", "error");
                                }
                            },
                            error: function () {Swal.fire("OMG...", "接口调用失败!", "error")
                            }
                        })
                    }
                })
            })
    
        </script>
    {% endblock %}

    参数解读:

    • 增加用户按钮:通过页面表单形式实现用户增加;
    • users:为后端 UserListViewcontext_object_name传递过去的;
    • 编辑按钮:和增加用户类型;
    • 删除按钮:通过 ajax 的弹窗形式进行删除,没有用到页面;
  • 效果图

1.4 用户更新

  • 视图配置

    # mysite/users/views.py
    
    from .form import UserModelForm
    from django.views.generic import UpdateView
    from django.contrib.auth import get_user_model
    from django.contrib.messages.views import SuccessMessageMixin
    
    User = get_user_model()
    
    class UserEditView(SuccessMessageMixin, UpdateView):
        """"更新用户"""
        template_name = 'users/form.html'
        model = User
        form_class = UserModelForm
        success_message = '%(username)s was update successfully'
    
        def get_success_url(self):
            # print(self.request.POST)
            if '_savedit' in self.request.POST:
                # print(self.object.pk)
                # 是一个 ID
                return reverse('users:useredit', kwargs={'pk':self.object.pk})
            return reverse('users:userlist')
    
    
        def form_valid(self, form):
            new_password = form.cleaned_data['password']
            # print(self.object)
            # 是一个用户
            self.object.set_password(new_password)
            self.object.save()
            return super(UserEditView, self).form_valid(form)

    参数解读:跟 CreateView 相似。

  • 模板配置

    用户增加 的模板统一,共用一个模板。

  • 效果图

1.5 用户删除

  • 视图配置

    from django.views.generic import DeleteView
    from django.contrib.auth import get_user_model
    
    User = get_user_model()
    
    class UserDelView(DeleteView):
        """删除用户"""
        model = User
    
        def post(self, request, *args, **kwargs):
            # pk = self.kwargs
            # print(pk)
            try:
                self.get_object().delete()
                res = {"code": 0, "result": "删除用户胜利"}
            except:
                log.error('delete user error:{}'.format(traceback.format_exc()))
                res = {"code": 1, "result": "删除用户失败"}
            return JsonResponse(res, safe=True)
  • 模板配置

    通过调用 ajax 删除用户,参考章节 用户查看 的模板文件。

  • 效果图

总结:终于码完这篇文章了,尽管看起来就 4 个我的项目:用户的增删改查,其实一点都不容易,五味杂陈啊。我还是把 CBV 里的 CreateViewListViewUpadteViewDeleteView 都一一对应起来了,其实办法还是有很多种的。

当初 用户治理 差不多就这样了,各位还能够继续去优化,做的更好,那么 用户登陆认证 怎么实现呢?待我去码下一篇文章 … 敬请期待!

如果喜爱的我的文章,欢送关注我的公众号:点滴技术,扫码关注,不定期分享

退出移动版