16

Django之简易用户系统(3)

 3 years ago
source link: https://segmentfault.com/a/1190000037763264
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

[toc]

1. 总体设计思路

Ufqiema.png!mobile

一套简单的用户管理系统,包含但不限如下功能:

  • 用户增加:用于新建用户;
  • 用户查询:用于查询用户信息;
  • 用户修改:用于修改用户信息;
  • 用户删除:用于删除用户信息;

最基本的功能就包括增、删、改、查了。

想要搭建好一套系统,前期肯定是要设计一套思路,大家按照上图对号入座即可。

下面,咋就开始实战了...

划重点了, 一定要动手一定要动手一定要动手 ...

2. 搭建简易用户系统

如果哪位同学还没学习过上两篇文章的,请速速去研究下,再来看这篇文章。

2.1 配置模型Model

hello\\models.py

创建一个类(class)对象,这就相当于数据中的一张表(table)。

# 创建数据库User表
class User(models.Model):
    # 性别, 元组用于下拉框
    sex = ((0, '男'), (1, '女'))
    # 用户名
    username = models.CharField(max_length=20, help_text='用户名')
    # 用户密码
    password = models.CharField(max_length=16, help_text='用户密码')
    # sex中的0,1是存放在数据库,中文男和女是在web前端展示
    sex = models.IntegerField(choices=sex, null=True, blank=True)
    # 手机号码
    phone = models.CharField(max_length=11, help_text='手机号码')

    # 对象获取返回值为用户名
    def __str__(self):
        return self.username

2. 2 写入数据库:

后台会转换成 sql 语句写入数据库,看起来是不是很方便,也不用太懂 sql 了,这也是 ORM 的强大之处。

(py369) [root@localhost devops]# python manage.py makemigrations hello
Migrations for 'hello':
  hello/migrations/0005_auto_20201105_2336.py
    - Create model User
    - Alter field id on devices
(py369) [root@localhost devops]# python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, hello, sessions
Running migrations:
  Applying hello.0005_auto_20201105_2336... OK

2.3 数据库验证表:

我是通过 Navicat Premium 工具连接数据库,进行可视化查看,你用哪个工具都可以。

bI3eYzR.png!mobile

2.4 路由URL配置:

hello\\urls.py

name='xxxx',这是命名空间的用法,常在模板使用此方式: hello:adduser ,等同于 hello/adduser.html , 好处就是不用担心你的 path 随意改变。

from django.urls import path
from django.urls import re_path
from hello import view

app_name = 'hello'
urlpatterns = [
    # FBV,通过函数方式,实现增删改查
    # 增加
    path('adduser/', view.adduser, name="adduser"),
    # 查询
    path('showuser/', view.showuser, name="showuser"),
    # 修改
    re_path('edituser/(?P<pk>[0-9]+)?/', view.edituser, name="edituser"),
    # 删除
    re_path('deluser/(?P<pk>[0-9]+)?/', view.deluser, name="deluser"),
]

2.5 用户增加

后台执行脚本配置:

hello\\view.py

from django.shortcuts import render
from django.http import HttpResponse, QueryDict
from django.shortcuts import get_object_or_404
from django.http import Http404
from hello.models import User
import traceback

# 用户增加函数
def adduser(request):
    msg = {}
    if request.method == 'POST':
        try:
            print(request.POST)
            # 将数据转为字典格式
            data = request.POST.dict()
            # 将数据一次性写入数据库
            User.objects.create(**data)
            msg = {'code':0, 'result':'已成功添加用户.'}
        except:
            msg = {'code':1, 'result':'添加用户失败:'.format(traceback.format_exc())}
    return render(request, "hello/adduser.html", {'msg':msg})

视图模板配置:

templates\\hello\\adduser.html

<!--继承母版-->
{% extends "base.html" %}
<!--重写title的内容-->
{% block title %} 用户添加 {% endblock %}
<!--重写body的内容-->
{% block body %}

<!--显示成功或失败的信息-->
{% if msg.code == 0 %}
    <p style="color: green"> {{ msg.result }}</p>
{% else %}
    <p style="color: red"> {{ msg.result }}</p>
{% endif%}

<div class="container">
    <h2 style="color: #666666">添加用户信息</h2><br>
<!--    表单-->
    <form method="post" action="">
        用户:
        <input type="text" name="username">
        <br><br>
        密码:
        <input type="password" name="password">
        <br><br>
        手机号:
        <input type="text" minlength="11" maxlength="11" name="phone">
        <br><br>
        性别:
        <input type="radio" name="sex" value="0" checked>男
        <input type="radio" name="sex" value="1" checked>女
        <br><br>
        <button type="submit">提交</button>
        <button type="reset">重置</button>
    </form>
</div>
{% endblock%}

前端展示效果如下:

打开浏览器,输入如下链接格式: http://ip/hello/adduser

jUvmyqq.png!mobile

用户提交,后台数据库验证:

认真填写好信息后,点击提交,成功的话就会显示 已成功添加用户 ,另外可以到后台 DB 去验证下。

我一口气创建了 6个 用户,我任性。

Nfe6NzY.png!mobile

备注:各位先忽略数据库表中密码是明文,后续实战中会是密文的,不用担心密码泄漏。

2.6 用户查询

后台执行脚本配置:

hello\\view.py

# 新增代码块
# 用户查看函数
def showuser(request):
    # http://192.168.8.130:8888/hello/showuser/?keyword=test001
    # 获取关键位置参数,get获取唯一值,''表示缺省参数,防止报错
    keyword = request.GET.get('keyword', '')
    # 获取所有数据
    users = User.objects.all()
    # 如果关键位置参数不为空
    if keyword:
        # 用户名不区分大小写过滤
        users = users.filter(username__icontains=keyword)
    # return 返回两个参数'users'和'keyword'传到前端
    return render(request, 'hello/showuser.html', {'users':users, 'keyword':keyword})

视图模板配置:

templates\\hello\\showuser.html

<!--继承母版-->
{% extends "base.html" %}
<!--重写title的内容-->
{% block title %} 用户查询 {% endblock %}
<!--重写body的内容-->
{% block body %}
<div class="container">
    <h2 style="color: #666666">查询用户信息</h2><br>
<!--搜索框-->
<!--    action重定向到http://ip/hello/showuser,showuser是命名空间name-->
<!--    'hello:showuser' 等同于 http://ip/hello/showuser/  -->
<!--    name='keyword' 表示 http://ip/hello/showuser/?keyword='test001'中的keyword参数-->
<!--    value 表示在文本框中显示-->
    <form action="{% url 'hello:showuser' %}">
        <input type="text" name="keyword" value="{{ keyword }}" placeholder="请输入想要查询的信息">
    <button type="submit"> 搜索 </button>
    </form>

<!--表格-->
    <table border="1">
        <thead>
            <tr>
                <th> ID </th>
                <th> 用户名 </th>
                <th> 密码 </th>
                <th> 手机号码 </th>
                <th> 性别 </th>
                <th> 操作 </th>
            </tr>
        </thead>
        <br>
        <tbody>
            {% for user in users %}
            <tr>
                <td> {{ user.id }} </td>
                <td> {{ user.username }} </td>
                <td> {{ user.password }} </td>
                <td> {{ user.phone }} </td>
                <td> {% if user.sex == 0 %}男 {% elif user.sex == 1 %}女 {% else %}none {% endif %} </td>
                <td>
                    <a href="{% url 'hello:edituser' user.id %}"> 更新 </a>
                    <a href="{% url 'hello:deluser' user.id %}"> 删除 </a>
<!--                    等同于如下,但不推荐此方式:-->
<!--                    <a href="/hello/edituser/{{user.id}}/"> 更新 </a>-->
<!--                    <a href="/hello/deluser/{{user.id}}/"> 删除 </a>-->
                </td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
</div>
{% endblock%}

前端展示效果如下:

3Yr6ZzE.png!mobile

查询用户,展示如下:

此时后台是通过 username 来过滤,后期我们会通过 Q 方法来过滤多个字段。

E7fiQvF.png!mobile

2.7 用户修改

后台执行脚本配置:

hello/view.py

重点说明:不管是用户查询还是删除,重点以 ID (数据库中的主键)进行操作,不要使用其他字段。

# 新增代码,用户修改函数
def edituser(request, **kwargs):
    msg = {}
    pk = kwargs.get('pk', '')
    # 先检查pk是否存在,不存在则报404错误
    user = get_object_or_404(User, pk=pk)
    if request.method == 'POST':
        try:
            data = request.POST.dict()
            User.objects.filter(pk=pk).update(**data)
            msg = {'code':0, 'result':'已成功更新用户'}
        except:
            msg = {'code':1, 'result':'用户更新失败: '.format(traceback.format_exc())}
      
    return render(request, 'hello/edituser.html', {'user':user, 'msg':msg})

视图模板配置

templates\\hello\\edituser.html

<!--继承母版-->
{% extends "base.html" %}
<!--重写title的内容-->
{% block title %} 更新用户 {% endblock %}
<!--重写body的内容-->
{% block body %}

<!--显示成功或失败的信息-->
{% if msg.code == 0 %}
    <p style="color: green"> {{ msg.result }}</p>
{% else %}
    <p style="color: red"> {{ msg.result }}</p>
{% endif %}

<div class="container">
    <h2 style="color: #666666">更新用户信息</h2><br>

    <form method="post" action="">
        用户名:
        <input type="text" name="username" value="{{ user.username }}">
        <br>
        <br>
        密码:
        <input type="password" name="password" value="{{ user.password }}">
        <br>
        <br>
        手机号码:
        <input type="text" name="phone" value="{{ user.phone }}">
        <br>
        <br>
        性别:
        {% if user.sex == 0 %}
            <input type="radio" name="sex" value="0" checked>男
            <input type="radio" name="sex" value="1">女
        {% else %}
            <input type="radio" name="sex" value="0" >男
            <input type="radio" name="sex" value="0" checked>女
        {% endif %}
        <br>
        <br>
        <button type="submit"> 提交 </button>
        <button> <a href="{% url 'hello:showuser' %}"> 取消 </a></button>
    </form>
</div>
{% endblock%}

前端展示效果如下:

在用户列表的操作项,点击 更新 ,跳转该页面:

JJZv2iV.png!mobile

修改用户,展示如下:

将用户名 test006 的性别修改为 ,结果如下:

VRFJZfv.png!mobile

pk 不存在的时候,测试效果如下:

Bf6Fnqj.png!mobile

后台数据库查表验证下:

URriArE.png!mobile

2.8 用户删除

后台执行脚本配置

hello\\view.py

# 新增代码, 用户删除函数
def deluser(request, **kwargs):
    msg = {}
    pk = kwargs.get('pk', '')
    try:
        # 获取单个用户信息
        user = User.objects.get(pk=pk)
    except User.DoesNotExist:
        # 如果用户不存在,则返回404错误
        raise Http404
    if request.method == 'POST':
        try:
            User.objects.get(pk=pk).delete()
            msg = {'code':0, 'result':'已成功删除用户'}
        except:
            msg = {'code': 1, 'result': '用户删除失败: '.format(traceback.format_exc())}
    return render(request, 'hello/deluser.html', {'user':user, 'msg':msg})

视图模板配置

templates\\hello\\deluser.html

<!--继承母版-->
{% extends "base.html" %}
<!--重写title的内容-->
{% block title %} 删除用户信息 {% endblock %}
<!--重写body的内容-->
{% block body %}

<!--显示成功或失败的信息-->
{% if msg.code == 0 %}
    <p style="color: green"> {{ msg.result }} {{ user.username }} </p>
{% else %}
    <p style="color: red"> {{ msg.result }}</p>
{% endif %}

<div class="container">
    <h2 style="color: #666666">删除用户信息</h2>

    <h1 style="color: red"> Are you sure to delete {{ user.username }}? </h1>

    <form method="post" action="">
        <button type="submit"> 确定 </button>
        <button> <a href="{% url 'hello:showuser' %}"> 取消 </a></button>
    </form>

</div>
{% endblock%}

删除用户,展示如下:

在用户列表的操作项,点击 删除 ,点击确定,已成功返回`:

yYrMzyu.png!mobile

删除失败效果如下:

aaQVvuR.png!mobile

至此,一套简易的用户系统已经完成啦,看起来是不是很简单,大家跟着练习一把,有问题,请随时讨论,谢谢。

如果觉得这篇文章不错,请点赞或分享到朋友圈吧!

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

Jju67v2.jpg!mobile


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK