django项目--用户管理功能

用户管理功能

一、业务功能分析

1. 业务需求分析

用户的增删改查,权限分组的控制。

2.功能分析

  • 用户列表
  • 修改用户
  • 删除用户

二、用户列表

1. 业务流程分析

  • 接收参数
  • 校验参数
  • 查询数据
  • 分页

2.接口设计

  1. 接口说明:
类目 说明
请求方法 GET
url定义 /admin/users/
参数格式 查询参数
  1. 参数说明:
参数名 类型 是否必须 描述
username 字符串 要查询的用户名
group 整数 要查询的group_id
is_staff 整数 用户是否员工
is_superuser 整数 父菜单id
page 整数 页码
  1. 返回数据

    html

3.后端代码

  1. 视图

    # 在myadmin/views.py下创建如下视图
    class UserListView(View):
        """
        用户列表视图
        """
    
        def get(self, request):
            user_queryset = User.objects.only('username', 'is_active', 'mobile', 'is_staff', 'is_superuser')
            groups = Group.objects.only('name').all()
            query_dict = {}
            # 检索
            groups__id = request.GET.get('group')
            if groups__id:
                try:
                    group_id = int(groups__id)
                    query_dict['groups__id'] = groups__id
                except Exception as e:
                    pass
    
            is_staff = request.GET.get('is_staff')
            if is_staff == '0':
                query_dict['is_staff'] = False
            if is_staff == '1':
                query_dict['is_staff'] = True
    
            is_superuser = request.GET.get('is_superuser')
            if is_superuser == '0':
                query_dict['is_superuser'] = False
            if is_superuser == '1':
                query_dict['is_superuser'] = True
    
            username = request.GET.get('username')
    
            if username:
                query_dict['username'] = username
    
            try:
                page = int(request.GET.get('page', 1))
            except Exception as e:
                page = 1
    
            paginater = Paginator(user_queryset.filter(**query_dict), 2)
    
            users = paginater.get_page(page)
            context = {
                'users': users,
                'groups': groups
            }
            context.update(query_dict)
            return render(request, 'myadmin/user/user_list.html', context=context)
    
  2. 路由

    # 在myadmin/urls.py中添加如下视图
    path('users/', views.UsersView.as_view(), name='user_list')
    

4.前端代码

  1. html

    <!-- 创建 templates/myadmin/user/user_list.html 模板-->
    {% extends 'admin/content_base.html' %}
    {% load static %}
    {% load news_customer_filters %}
    {% block page_header %}
        系统设置
    {% endblock %}
    {% block page_option %}
        用户管理
    {% endblock %}
    {% block content %}
        <div class="box">
            <div class="box-header with-border">
                <h3 class="box-title">用户列表</h3>
            </div>
            <!-- /.box-header -->
    
            <div class="box-body">
                <div style="margin-bottom: 10px">
                    <form class="form-inline user-query">
                        <div class="form-group">
                            <label for="">用户名</label>
                            <input type="text" class="form-control" name="username" value="{{ username }}">
                        </div>
                        <div class="form-group">
                            <label for="">分组</label>
                            <select name="group" id="" class="form-control">
                                <option value="">所有</option>
                                {% for group in groups %}
    
                                    <option {% if groups__id == group.id %}selected{% endif %}
                                            value="{{ group.id }}">{{ group.name }}</option>
    
                                {% endfor %}
                            </select>
                        </div>
                        <div class="form-group">
                            <label for="">是否员工</label>
                            <select name="is_staff" id="" class="form-control">
                                <option value="">所有</option>
    
                                <option {% if is_staff is True %}selected{% endif %} value="1">是</option>
                                <option {% if is_staff is False %}selected{% endif %} value="0">否</option>
                            </select>
                        </div>
                        <div class="form-group">
                            <label for="">是否管理员</label>
                            <select name="is_superuser" id="" class="form-control">
                                <option value="">所有</option>
                                <option {% if is_superuser is True %}selected{% endif %} value="1">是</option>
                                <option {% if is_superuser is False %}selected{% endif %} value="0">否</option>
                            </select>
                        </div>
                        <button type="button" class="btn btn-info query">查询</button>
                        <button type="button" class="btn btn-default reset">重置</button>
                    </form>
                </div>
    
                <table class="table table-bordered">
                    <tbody>
                    <tr>
                        <th>#</th>
                        <th>用户名</th>
                        <th>电话</th>
                        <th>是否可用</th>
                        <th>是否员工</th>
                        <th>是否管理员</th>
                    </tr>
                    {% for user in users %}
                        <tr>
                            <td style="width: 40px"><a href="#" data-id="{{ user.id }}">{{ forloop.counter }}</a></td>
                            <td>{{ user.username }}</td>
                            <td>{{ user.mobile }}</td>
                            <td>{% if user.is_active %}是{% else %}否{% endif %}</td>
                            <td>{% if user.is_staff %}是{% else %}否{% endif %}</td>
                            <td>{% if user.is_superuser %}是{% else %}否{% endif %}</td>
    
                        </tr>
    
                    {% endfor %}
    
                    </tbody>
                </table>
    
    
            </div>
            <!-- 分页 -->
            <div class="box-footer clearfix">
                <div class="row">
                    <div class="col-sm-6">
                        <div class="dataTables_info" id="example2_info" role="status" aria-live="polite">总共:{{ users.paginator.count }}条 第{{ users.start_index }}到{{ users.end_index }}条
                        </div>
                    </div>
                    <div class="col-sm-6">
                        <ul class="pagination pagination-sm no-margin pull-right">
                            <li {% if not users.has_previous %}class="disabled"{% endif %} data-page="{{ users.number|add:-1 }}"><a href="#">«</a></li>
                        {% for n in users|page_bar %}
                            <li {% if n == users.number %}class="active" {% endif %} data-page="{{ n }}"><a href="#">{{ n }}</a></li>
                        {% endfor %}
                            <li {% if not users.has_next %}class="disabled"{% endif %} data-page="{{ users.number|add:1 }}"><a href="#">»</a></li>
                        </ul>
                    </div>
                </div>
    
            </div>
    
        </div>
    {% endblock %}
    {% block script %}
        <script src="{% static 'js/myadmin/user/user_list.js' %}"></script>
    {% endblock %}
    
    
  2. js

    // 创建static/js/myadmin/user/user.js
    $(() => {
        let $queryForm = $('form.user-query');       // 查询表单
        let $queryBtn = $('form.user-query button.query');    // 查询按钮
        let $resetBtn = $('form.user-query button.reset');    // 重置按钮
        // 查询
        $queryBtn.click(() => {
    
            $
                .ajax({
                    url: $('.sidebar-menu li.active a').data('url'),
                    data: $queryForm.serialize(),
                    type: 'GET'
                })
                .done((res) => {
                    $('#content').html(res)
                })
                .fail(() => {
                    message.showError('服务器超时,请重试!')
                })
        });
    
        // 重置
        $resetBtn.click(() => {
            $queryForm[0].reset();
            $
                .ajax({
                    url: $('.sidebar-menu li.active a').data('url'),
                    type: 'GET'
                })
                .done((res) => {
                    $('#content').html(res)
                })
                .fail(() => {
                    message.showError('服务器超时,请重试!')
                })
        });
    
        // 分页 给非
        let $pageLi = $('ul.pagination li').not('.active').not('.disabled');
        $pageLi.click(function () {
            let $this = $(this);
            $.each($queryForm.serializeArray(), function () {
                queryData[this.name] = this.value
            });
            queryData['page'] = $this.data('page')
    
            $
                .ajax({
                    url: $('.sidebar-menu li.active a').data('url'),
                    data: queryData,
                    type: 'GET'
                })
                .done((res) => {
                    $('#content').html(res)
                })
                .fail(() => {
                    message.showError('服务器超时,请重试!')
                })
    
        })
    });
    

三、用户详情页面

1.接口设计

  1. 接口说明:
类目 说明
请求方法 GET
url定义 /admin/user/<int:user_id>/
参数格式 路径参数
  1. 参数说明:
参数名 类型 是否必须 描述
user_id 整数 要查询的用户id
  1. 返回数据

    html

2. 后端代码

  1. 视图

    # 在myadmin/views.py中添加如下视图
    
    class UserUpdateView(View):
        """
        用户更新视图
        url:/admin/user/<int:user_id>
        """
        def get(self, request, user_id):
            user = User.objects.filter(id=user_id).first()
            if user:
                form = UserModelForm(instance=user)
            else:
                form = UserModelForm()
            return render(request, 'myadmin/user/user_detail.html', context={'form': form})
    
  2. 路由

    # 在myadmin/urls.py中添加如下路由
    path('user/<int:user_id>/', views.UserUpdateView.as_view(), name='user_update')
    
  3. 表单

    # 在myadmin/forms.py中定义如下表单
    class UserModelForm(forms.ModelForm):
    
        class Meta:
            model = User
            fields = ['username', 'mobile', 'is_staff', 'is_superuser', 'is_active', 'groups']
    

3.前端代码

  1. html

    <!-- 新建 myadmin/user/user_detail.html 模板 -->
    {% extends 'myadmin/content_base.html' %}
    {% load static %}
    {% load admin_customer_tags %}
    {% block page_header %}
        系统设置
    {% endblock %}
    {% block page_option %}
        用户管理
    {% endblock %}
    {% block content %}
        <div class="box box-primary">
            <div class="box-header with-border">
                <h3 class="box-title">用户详情</h3>
            </div>
            <!-- /.box-header -->
            <!-- form start -->
            <div class="box-body">
                <div class="row">
                    <div class="col-md-3"></div>
                    <div class="col-md-6">
                        <form class="form-horizontal">
                            {% csrf_token %}
    
                            {% for field in form %}
                                {% if field.name in 'is_staff,is_active,is_superuser' %}
                                    <div class="form-group">
    
                                        <div class="col-sm-offset-2 col-sm-10">
    
                                            <div class="checkbox">
                                                <label for="{{ field.id_for_label }}">{{ field }}{{ field.label }}</label>
                                            </div>
                                        </div>
    
                                    </div>
                                {% else %}
                                    <div class="form-group {% if field.errors %}has-error{% endif %}">
    
                                        <label for="{{ field.id_for_label }}"
                                               class="col-sm-2 control-label">{{ field.label }}</label>
    
                                        <div class="col-sm-10">
                                            {% for error in field.errors %}
                                                <label class="control-label"
                                                       for="{{ field.id_for_label }}">{{ error }}</label>
                                            {% endfor %}
                                            {% add_class field 'form-control' %}
                                        </div>
                                    </div>
                                {% endif %}
                            {% endfor %}
    
    
                        </form>
                    </div>
                    <div class="col-md-3"></div>
                </div>
            </div>
            <div class="box-footer">
    
                        <button type="button" class="btn btn-default back">返回</button>
                        <button type="button" class="btn btn-primary pull-right save
                                                     " data-url="{% url 'myadmin:user_update' form.instance.id %}">保存</button>
    
    
            </div>
        </div>
    {% endblock %}
    
  2. js代码

    // 在 admin/user/user.js中添加如下代码
    
    ...
        // 用户详情
        $('tr').each(function () {
            $(this).children('td:first').click(function () {
                $('#content').load(
                    $(this).data('url'),
                    (response, status, xhr) => {
                        if (status !== 'success') {
                            message.showError('服务器超时,请重试!')
                        }
                    }
                );
            })
        });
    ...
    // 注意在user_list中在相应的tr中添加data-url的属性
    <td style="width: 40px" data-url="{% url 'myadmin:user_update' user.id %}">
    

四、修改用户

1.接口设计

  1. 接口说明:
类目 说明
请求方法 PUT
url定义 /admin/user/<int:user_id>
参数格式 路径参数+表单参数
  1. 参数说明:
参数名 类型 是否必须 描述
user_id 整数 用户id
username 字符串 用户名
mobile 字符串 手机号码
is_staff 字符串 是否职员
is_superuser 字符串 是否超级用户
is_active 字符串 渲染图标类名
  1. 返回数据

    # 添加正常返回json数据
    {
    "errno": "0",
    "errmsg": "用户修改成功!"
    }
    

    如果有错误,返回html表单

2.后端代码

  1. 视图

    # 在admin/views.py中的UserUpdateView视图中添加put方法
    class UserUpdateView(View):
        """
        用户更新视图
        url:/admin/user/<int:user_id>
        """
        def get(self, request, user_id):
            user = User.objects.filter(id=user_id).first()
            if user:
                form = UserModelForm(instance=user)
            else:
                form = UserModelForm()
            return render(request, 'admin/user/user_detail.html', context={'form': form})
    
        def put(self, request, user_id):
            user = User.objects.filter(id=user_id).first()
            put = QueryDict(request.body)
            if user:
                form = UserModelForm(put, instance=user)
            else:
                form = UserModelForm()
            if form.is_valid():
                form.save()
                return json_response()
            else:
                return render(request, 'admin/user/user_detail.html', context={'form': form})
    

3.前端代码

  1. js

    // 新建 js/admin/user/user_detail.js 注意在user_detail.html中引入
    $(() => {
        $('.box-footer button.back').click(() => {
            $('#content').load(
                $('.sidebar-menu li.active a').data('url'),
                (response, status, xhr) => {
                    if (status !== 'success') {
                        message.showError('服务器超时,请重试!')
                    }
                }
            );
        });
    
        $('.box-footer button.save').click(function () {
            $
                .ajax({
                    url: $(this).data('url'),
                    data: $('form').serialize(),
                    type: 'PUT'
                })
                .done((res) => {
                    if (res.errno === '0') {
                        message.showSuccess('修改用户成功!');
                        $('#content').load(
                            $('.sidebar-menu li.active a').data('url'),
                            (response, status, xhr) => {
                                if (status !== 'success') {
                                    message.showError('服务器超时,请重试!')
                                }
                            }
                        );
                    }else {
                        $('#content').html(res)
                    }
                })
                .fail((res)=>{
                    message.showError('服务器超时,请重试!')
                })
        })
    
    });
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容