• 欢迎访问极客猴,分享 Python 入门,网络爬虫,数据分析,赚钱思维相关的技术与思维QQ群
  • 本站点文章首发于微信公众号【极客猴】,欢迎关注,第一时间接受文章推送~
  • 如果您觉得本站非常有看点,那么赶紧使用 Ctrl+D 收藏极客猴吧

Django 实战1:搭建属于自己社工查询系(下)

Django 入门 猴哥 3年前 (2018-04-10) 38次浏览 0个评论
文章目录[隐藏]

上篇文章已经完成框架搭建,本文接着上篇的内容继续讲解。本片主要的说三点内容,分别是:根据条件查询数据、根据查询结果显示不同内容、将查询数据填充到页面上。

1.逻辑优化

在上篇文章,我在原来的 url 地址中处理用户提交的表单数据。Url 值改变了,但是页面没有刷新。同时,表单数据没有进行分类。这会导致用户不管提交什么数据,页面就呈现什么数据。

而正常的逻辑应该是这样。如果用户访问的是首页,那么不需要填充任何数据以及展示提示框。

Django 实战1:搭建属于自己社工查询系(下)

如果用户提交了表单数据,但是数据库中没有查询到数据,则提醒下用户没有查询到相关数据。

Django 实战1:搭建属于自己社工查询系(下)

如果用户提交了表单数据,数据库也能查询到数据。页面需要提醒用户查询到数据,并将查询结果展示出来。

Django 实战1:搭建属于自己社工查询系(下)

为了解决这个问题,我通过定义一个变量 countNum 来区分。

2.根据查询结果显示不同内容

2-1.视图改造

按照解决方案,我们需要对 V 层进行改造。定义全局变量 countNum,初始化为 -1。如果用户访问的是首页,就直接返回。如果用户提交表单数据,数据库查询不到数据。则将 countNum 赋值为 0 ,然后返回。如果用户提交表单数据,数据库查询不到数据,就返回数据总条。

# views.py
def index(request):
    templateView = 'index.html'
    countNum = -1
    keywords = ''

    if request.method == 'GET':

        form = QueryUserForm(request.GET)
        # 验证表单
        if form.is_valid():
            # 过滤需要的数据
            condition = form.cleaned_data['condition']
            keywords = form.cleaned_data['queryContent']

            print('condition == ' + condition)
            print('keywords == ' + keywords)

            countNum = 0
            # 查询结果
            # 假设经过查询, 一共获取到 3 条数据
            countNum = 3
            if countNum != 0:
                return render(request, templateView, {
                    'countNum': countNum,
                    'keywords': keywords,
                    'form': form,
                })
            # 查询不到数据, 显示没有数据的浮窗
            if countNum == 0:
                return render(request, templateView, {
                    'countNum': countNum,
                    'keywords': keywords,
                    'form': form,
                })
        # 直接访问主页, 显示的内容
        else:
            return render(request, templateView, {'countNum': countNum,  'form': form})

2-2.模板改造

T 层(模板)需要根据 V 层(视图)透传过来的 countNum 的值进行判断,然后渲染相应的内容。

# index.html
<!DOCTYPE html>
<html>
<body>
    <div class="container" id="container">
        <!-- 前面代码不变 -->
        {% if countNum == -1 %}
            <!-- 显示首页内容, 不需要做处理 -->
        {% else %}
            <!-- 查询不到数据, 提醒用户更换 关键词或者类型 -->
            {% if countNum == 0 %}
                <div class="alert alert-warning alert-dismissible col-md-10 col-md-offset-1" role="alert">
                    <button type="button" class="close" data-dismiss="alert">
                    <span aria-hidden="true">×</span>
                    <span class="sr-only">Close</span></button>
                    找不到与<b>&nbsp{{ keywords }}&nbsp</b>相关的结果。请更换其他<b>&nbsp关键词或类型&nbsp</b>试试。</div></div>
            {% else %}
                <!-- 显示总数以及查询耗时 
                     打印表格、说明头部行、查询到的数据-->
                <div class="row">
                <div class="alert alert-success alert-dismissible col-md-10 col-md-offset-1" role="alert">
                    <button type="button" class="close" data-dismiss="alert">
                    <span aria-hidden="true">×</span>
                    <span class="sr-only">Close</span></button>
                    找到与<b>&nbsp {{ keywords }} &nbsp</b>相关的结果 {{ countNum }} 个。用时 {{ time }} 秒。</div>
                <div class="table-responsive col-md-12">
                    <table class="table table-striped table-hover">
                    <tr>
                    <th class="text-center">用户名</th>
                    <th class="text-center">密码</th>
                    <th class="text-center">姓名</th>
                    <th class="text-center">邮箱</th>
                    <th class="text-center">QQ 号码</th>
                    <th class="text-center">数据来源</th>
                    </tr>
                    <!-- 填充查询到的数据 -->
                    </table></div></div>
            {% endif %}
        {% endif %}
    </div>
</body>
</html>

3.根据条件查询数据

模型层主要跟数据库打交道, 数据库存储数据的地方。所以查询数据内容其实是模型知识地运用。

考虑到数据库中可能存在多条关键字(queryContent)相关的数据,所以需要使用 filter() 来匹配。我使用的匹配模式是精确匹配,所以无须使用正则表达式来匹配。直接把关键字作为模型过滤条件就可以了,实现代码如下:

# 把 Socialusers 的 username 属性作为 condition 来查询数据。
# 查询内容是用户输入的内容 queryContent
user_list = Socialusers.objects.filter(username=keywords)
# 获取总条数
countNum = user_list.count()

condition 记录用户选择下拉框的条目值。该变量的值决定模型 Socialusers 要使用哪个属性来查询。由于 python 没有 switch 语句,只能写多个 elif 来处理多个条件。那么代码可以这么实现:

# views.py
def index(request):
    templateView = 'index.html'
    countNum = -1
    keywords = ''
    time = 0

    if request.method == 'GET':
        form = QueryUserForm(request.GET)
        # 验证表单
        if form.is_valid():
            # 过滤需要的数据
            condition = form.cleaned_data['condition']
            keywords = form.cleaned_data['queryContent']

            print('condition == ' + condition)
            print('keywords == ' + keywords)

            countNum = 0
            # 查询结果
            if condition == 'username':
                user_list = Socialusers.objects.filter(username=keywords)
                countNum = user_list.count()
                # 获取查询耗时
                time = (connection.queries)[0].get('time')
                print('user_list size=== ', user_list.count())
                print('time === ', time)

                # 显示分页操作, 每页显示 20 条
                paginator = Paginator(user_list, 20)
                page = request.GET.get('page')
                try:
                    users = paginator.page(page)
                except PageNotAnInteger:
                    # 如果请求的页数不是整数,返回第一页。
                    users = paginator.page(1)
                except EmptyPage:
                    # 如果请求的页数不在合法的页数范围内,返回结果的最后一页。
                    users = paginator.page(paginator.num_pages)

                return render(request, templateView, {
                        'countNum': countNum,
                        'condition': condition,
                        'keywords': keywords,
                        'form': form,
                        'users': users,
                        'time': time,
                    })
            elif condition == 'password':
                # 后面的代码逻辑跟前面类似, 只不过 filer() 的内容改变了。

            # 查询不到数据, 显示没有数据的浮窗
            if countNum == 0:
                return render(request, templateView, {
                    'countNum': countNum,
                    'keywords': keywords,
                    'form': form,
                })
        # 直接访问主页, 显示的内容
        else:
            return render(request, templateView, {'countNum': countNum,  'form': form})

代码中使用到了分页 Paginator,这部分后面会继续讲解。

4.填充数据

最后一步工作就是在模板中填充查询到的数据。因为我们在视图中将查询到 user_list 集合传递给模板。这里要注意的是,user_list 其实是一个查询集 QuerySet,不是真正意义上的列表,只不过命名为列表而已。在模板中,使用一个 for 循环逐一解析每个模型的值,就能完成数据填充工作。

# index.html
<!-- 填充查询到的数据 --> 
# 在下面的注释下面,打印查询到的数据
{% for user in users %}
<tr>
<td class="text-center">{{ user.username }}</td>
<td class="text-center">{{ user.password }}</td>
<td class="text-center">{{ user.chinesename }}</td>
<td class="text-center">{{ user.email }}</td>
<td class="text-center">{{ user.qq }}</td>
<td class="text-center">{{ user.source }}</td>
</tr>
{% endfor %}

第一个实战项目到这里就结束了。主要目的是让大家明白如何将模型、表单、模板、视图串联起来。后面的文章会讲解高级用法以及前面遗漏的细节内容。

5.源码

如果你想获取项目的源码, 点击按钮进行下载。
下载地址:点击下载


Django 实战1:搭建属于自己社工查询系(下)

文章首发于微信公众号【极客猴】,欢迎扫码关注获取第一时间推送


极客猴版权所有,内容均为原创丨本网站采用共享 4.0 国际 CC BY-NC-SA 4.0 许可协议
文章标题:Django 实战1:搭建属于自己社工查询系(下)
转载请保留页面地址:https://geekmonkey.top/165.html
喜欢 (0)
[赞赏码]
分享 (0)
猴哥
关于作者:
分享自己总结的Python爬虫,Web开发,数据分析的心得。此外还输出自己的思考内容,涉猎产品知识、个人成长等,每周给你带来头脑大爆炸
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址