最新消息:欢迎光临 魔力 • Python!大家可以点开导航菜单中的【学习目录】,这个目录类似图书目录,更加方便学习!

Django2:Web项目开发入门笔记(8)

Django教程 小楼一夜听春语 3866浏览 0评论

这一篇教程,我们一起来使用Django通过HTML页面进行数据库的访问。

首先,我们先来看一下页面中的功能。

这些功能包括:

  • 查询数据库中所有商品数据;
  • 查询数据库中指定名称的商品数据;
  • 查询数据库中指定价格区间的商品数据;
  • 查询数据库中的指定数据并排序。

在开始编写这些功能之前,我们先来准备数据库中的数据。

在上一篇教程的基础上,我们在已创建好的数据表中添加更多的数据。

铅笔,10,1.5
橡皮,20,0.5
直尺,15,2.4
作业本,18,2.5
笔记本,21,6.2
钢笔,35,9.9
铅笔盒,33,12.5
墨水,12,5.0
曲别针,9,1.0
订书器,18,8.0
订书钉,15,3.6
裁纸刀,12,7.5
签字笔,20,6.8
签字笔芯,50,3.5
自动铅笔,32,4.2
自动笔芯,36,2.1

这些数据如果通过命令行终端手动添加的话,实在是太累了。

我们可以打开PyCharm,在应用文件夹中新建(New)一个文件(File),命名为“data”,把这些数据保存在文件中。

然后再新建(New)一个Python文件(Python File)编写一个脚本,进行数据导入。

示例代码:

from MySite.models import Goods

with open('data', 'r', encoding='utf-8') as file:  # 打开文件创建文件对象(注意编码)
    for line in file:  # 读取每一行
        lst = line.strip().split(',')  # 将每一行中的商品信息转换为列表
        state = Goods.objects.create(goods_name=lst[0], goods_number=lst[1], goods_price=lst[2])  # 添加数据到数据库
        print(state)  # 显示输出添加数据的结果

然后,我们运行脚本代码。

这时候,大家会看到引发了一个异常:django.core.exceptions.AppRegistryNotReady: Apps aren’t loaded yet.(应用程序没有载入)

这是因为,我们使用的是Django框架,进行数据库的操作,需要框架的支持。

而我们单独运行写好的脚本时,Django框架没有被启动,这就会导致异常发生。

所以,在刚才脚本代码的开始,我们加入以下代码:

示例代码:

import os
import django

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "MyWeb.settings")  # 关联默认设置
django.setup()  # 装载Django

注意,程序代码的执行是从上至下的,所以这段代码一定要放在前一段代码的上方。

这样,在Django启动后,才会导入Goods,不会引发异常。

当我们执行完上方代码,会看到多个类似“Goods object (编号)”的结果,这些结果表名数据添加是有效的,结果中的编号是因为我们创建数据表的时候没有指定主键,数据库自动给添加的id列作为主键。

这里给大家推荐一款小工具:sqlite studio。【点此下载

这款工具,能够打开SQLite的数据文件,进行可视化操作。(注意不要把这个工具放在中文目录下,否则会报错,无法打开!)

添加好了数据之后,接下来,我们分步完成各个功能。

一、创建模板

1、首页模板

我们在模板文件夹中新建模板文件“index.html”,并在这个文件中添加4个表单。

示例代码:(index.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h3>商品查询</h3>
<form action="/all/" method="GET">
    <input type="submit" value="查询全部">
</form>
<br>
<form action="/search_name/" method="GET">
    <input type="text" name="goods_name">
    <input type="submit" value="名称查询">
</form>
<br>
<form action="/search_price/" method="GET">
    <input type="text" name="min_price">
    <input type="text" name="max_price">
    <input type="submit" value="价格区间查询">
</form>
<br>
<form action="/search_sort/" method="GET">
    <input type="radio" name="sort" value="all_asc" checked>查询全部并升序排列
    <input type="radio" name="sort" value="all_desc">查询全部并降序排列
    <input type="radio" name="sort" value="result_asc">条件查询并升序排列
    <input type="submit" value="排序查询">
</form>
</body>
</html>

如上方代码所示,每个表单“form”都有不同“action”属性,这些属性就是点击提交“submit”按钮时,打开的URL。

并且,在这些表单中添加了不同的“input”标签,形成了不同的表单内容。

“input”标签中的“name”属性就是URL中参数的名称,而“value”属性或文本框中输入的内容就是参数的值。

以第2个表单为例,当点击提交按钮时,就会打开URL“http://IP:端口号(或域名)/search_name/?goods_name=文本框中的输入内容”

另外,还要注意的是第4个表单,里面“input”标签的“type”属性是“radio”,也就是单选按钮。

如果想让单选按钮默认选中,需要在标签属性中添加“checked”属性。

如果想让多个单选按钮只有一个能够被选中,需要将这些单选按钮的“name”属性添加相同的名称(编组操作)。

提交表单的时候,URL中“name”属性值所对应的参数值就是被选中单选按钮的“value”值。

2、搜索结果页模板

在模板文件夹中新建搜索结果页面的模板“search_result.html”。

在这个模板所定义的页面内容中,我们要展示搜索结果的列表。

我们进行查询时,能够获得查询结果的数据对象(例如:goods_list ),所以,在模板中我们对数据对象进行遍历,输出列表内容。

示例代码:(search_result.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>搜索结果</title>
</head>
<body>
<h3>搜索结果:</h3>
<ol>
{% for goods_info in goods_list %}
   <li><label style="display:inline-block;width:120px;">名称:{{ goods_info.goods_name }}</label>
    <label style="display:inline-block;width:90px;">数量:{{ goods_info.goods_number }}</label>
    <label style="display:inline-block;width:90px;">价格:{{ goods_info.goods_price }}</label>
{% empty %}
    没有查询结果!
{% endfor %}
</ol>
</body>
</html>

这里用到了“ol”标签,这个标签中的“li”子标签能够自动产生递增的数字编号。

然后,每一行的数据字段都使用“label”标签进行呈现,通过设置“label”标签的样式,让内容有更好的排列效果。

二、设置URL分发

我们创建模板时,已经定义好了提交的URL,接下来就要在“urls.py”文件中进行分发配置。

先导入视图模块,然后在urlpatterns列表中,我们添加一些新的语句。

示例代码:

from MySite import  views as siteviews
path('',siteviews.index),
path('all/', siteviews.searchall),
path('search_name/', siteviews.searchname),
path('search_price/', siteviews.searchprice),
path('search_sort/', siteviews.searchsort),

三、编写视图函数

根据URL分发设置中调用的函数名称,我们定义视图函数。

1、首页视图函数

示例代码:

def index(request):
    return render(request, 'index.html')

2、查询全部数据的视图函数

示例代码:

def searchall(request):
    goods_list = Goods.objects.all()
    return render(request, 'search_result.html', {'goods_list': goods_list})

通过模型对象调用all()方法,就能够获取到数据库中所有的数据。

我们将获取到的数据对象传入模板的页面内容中进行读取。

查询结果页面显示内容:

3、查询指定商品名称数据的视图函数

示例代码:

def searchname(request):
    goods_name = request.GET['goods_name']
    goods_list = Goods.objects.filter(goods_name=goods_name)  # 完全匹配搜索关键字
    # goods_list = Goods.objects.get(goods_name=goods_name)# 查询满足条件的一个结果(查询到多个结果时异常)
    # goods_list = Goods.objects.filter(goods_name__contains=goods_name)  # 模糊匹配搜索关键字
    return render(request, 'search_result.html', {'goods_list': goods_list})

每个商品名称都是唯一的,在获取数据对象时可以使用get()方法(第1条被注释的语句),但是这个方法获取的数据对象不可迭代,会导致模板无法加载数据产生异常。

所以,在这里我们使用filter()方法来获取可迭代的数据对象。

如果filter方法的参数类似“(goods_name=goods_name)”,在查询时会进行精确匹配。

例如,查询商品名称为“铅笔”的数据。

查询结果页面显示内容:

需要模糊查询的话,我们需要给参数添加查询的匹配规则,添加匹配规则就是在参数名称后方输入2个下划线和匹配规则的名称。

例如“contains”就是包含匹配,只要字段值中包含参数值即可查询出来,即模糊查询(第2条被注释的语句)。

例如,同样输入查询的商品名称为“铅笔”。

查询结果页面显示内容:

匹配规则有很多种,作用如下:(点击每个规则可查询详细文档)

了解了以上内容,相信大家能够找出更多的查询方式。

3、查询某一价格区间数据视图的视图函数

示例代码:

from django.db.models import Q
def searchprice(request):
    min_price = request.GET['min_price']
    max_price = request.GET['max_price']
    goods_list = Goods.objects.filter(goods_price__gt=min_price, goods_price__lt=max_price)  # 满足全部多个条件
    # goods_list = Goods.objects.filter(Q(goods_price=0.5) | Q(goods_price=2.4)) # 满足任何一个条件
    return render(request, 'search_result.html', {'goods_list': goods_list})

在上方代码中大家能够看到,当进行满足多个条件的查询时,我们只需要在filter()方法中写入多个参数内容就可以了(也可以使用下方介绍的“Q”类)。

例如,查询价格大于4元并且小于6元的商品。

查询结果页面显示内容:

而如果满足任何一个条件时进行数据查询,我们需要使用Django数据模型模块中提供的“Q”类,多个条件需要创建多个“Q”的对象并用竖线“|”(或者)分隔。(被注释的语句)

关于“Q”类,它的作用是将过滤器参数封装为可以在逻辑上进行组合的对象,可以使用符号“&”(表示AND)或“|”(表示OR)进行组合。

4、对不同查询结果进行排序的视图函数

对于排序,如果查询全部数据并升序排列,我们只需要调用order_by()方法,并输入排序的字段名称为参数。

而查询全部数据并进行降序排列,同样调用order_by()方法,只是参数中的字段名称前面加上减号“-”即可。

而且,我们也可以通过对filter()方法的查询结果,调用order_by()方法,并依据某一字段进行排序。

示例代码:

def searchsort(request):
    sort = {'all_asc': Goods.objects.order_by('goods_price'),  # 查询全部结果后升序排列
            'all_desc': Goods.objects.order_by('-goods_price'),  # 查询全部结果后降序排列
            'result_asc': Goods.objects.filter(goods_price__lt='5').order_by('goods_price')  # 对某一查询结果排序
            }
    return render(request, 'search_result.html', {'goods_list': sort[request.GET['sort']]})

提示:上方代码并没有通过条件判断分别组织查询数据的语句进行数据查询,而是使用字典来完成。

以上就是通过查询数据操作对Django的数据库操作举了几个简单的例子。

实际上,Django中对数据库的操作有很多,更多的数据库操作相关内容,还是建议大家多了解一下官方文档或者通过搜索引擎查阅相关的中文资料。

本节练习源代码:【点此下载

转载请注明:魔力Python » Django2:Web项目开发入门笔记(8)

头像
发表我的评论
取消评论

表情

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

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网站 (可选)

网友最新评论 (9)

  1. 头像
    写的很详细
    hy1年前 (2018-08-25)回复
  2. 头像
    艰难的学习中
    chensir10个月前 (11-07)回复
  3. 头像
    我没用PyCharm,在导入数据这一步。我是将脚本和data文件同时放到Project的根目录下面才能执行成功。 如果放在APP根目录下会报MyWeb找不到。
    时间的切面10个月前 (11-30)回复
  4. 头像
    写views的时候,要先导入Goods。 from MySite.models import Goods 否则报错啦。
    miaocbin10个月前 (11-30)回复
    • 小楼一夜听春语
      第一段代码的第一句不就是?
      小楼一夜听春语10个月前 (11-30)回复
  5. 头像
    请问楼大神,价格区间这里,如果什么都不输入会报错,要捕捉这个异常,给予提示或者直接反馈没有查询结果,怎么改造程序呢。
    miaocbin10个月前 (11-30)回复
    • 小楼一夜听春语
      直接js中进行判断就可以。
      小楼一夜听春语10个月前 (11-30)回复
  6. 头像
    个人觉得应该利用判断条件来写最后的查询,如果以字典的形式会产生很多的数据库访问,性能不好,个人见解。。。
    16个月前 (03-15)回复
    • 小楼一夜听春语
      嗯,忽略了这个问题。
      小楼一夜听春语6个月前 (03-18)回复