读取数据库数据

获取全部记录


点击这里,边看视频讲解,边学习以下内容

前面,我们已经创建了数据库和 Customer表。

现在我们来实现一个功能:浏览器访问 sales/customers/ ,我们的服务端就返回系统中所有的客户记录给浏览器。


我们先实现一个函数,来处理浏览器发出的URL为 sales/customers/ 的访问请求, 我们需要返回 数据库中 customer 表 所有记录。

Django 中 对数据库表的操作, 应该都通过 Model对象 实现对数据的读写,而不是通过SQL语句。

比如,这里我们要获取 customer 表 所有记录, 该表是和我们前面定义的 Customer 类管理的。

我们可以这样获取所有的表记录:

在文件sales/views.py 中,定义一个listcustomers 函数,内容如下:

# 导入 Customer 对象定义
from  common.models import  Customer

def listcustomers(request):
    # 返回一个 QuerySet 对象 ,包含所有的表记录
    # 每条表记录都是是一个dict对象,
    # key 是字段名,value 是 字段值
    qs = Customer.objects.values()

    # 定义返回字符串
    retStr = ''
    for customer in  qs:
        for name,value in customer.items():
            retStr += f'{name} : {value} | '

        # <br> 表示换行
        retStr += '<br>'

    return HttpResponse(retStr)

Customer.objects.values() 就会返回一个 QuerySet 对象,这个对象是Django 定义的,在这里它包含所有的Customer 表记录。

QuerySet 对象 可以使用 for 循环遍历取出里面所有的元素。每个元素 对应 一条表记录。

每条表记录元素都是一个dict对象,其中 每个元素的 key 是表字段名,value 是 该记录的字段值

上面的代码就可以将 每条记录的信息存储到字符串中 返回给 前端浏览器。

我们还需要修改路由表, 加上对 sales/customers/ url请求的 路由。

前面,我们在bysms\urls.py 主路由文件中,已经有如下的记录了

    # 凡是 url 以 sales/  开头的,
    # 都根据 sales.urls 里面的 子路由表进行路由
    path('sales/', include('sales.urls')),

这条URL记录,指明 凡是 url 以 sales/ 开头的,都根据 sales.urls 里面的 子路由表进行路由。

我们只需修改 sales/urls.py 即可,添加如下记录

    path('customers/', views.listcustomers),

大家可以使用 admin 登录, 再添加一些 客户记录。

然后可以在浏览器输入如下 网址: http://127.0.0.1/sales/customers/

回车后,浏览器显示结果类似如下

image

和我们数据库中的记录信息一致

image


过滤条件


点击这里,边看视频讲解,边学习以下内容

有的时候,我们需要根据过滤条件查询部分客户信息。

比如,当用户在浏览器输入 /sales/customers/?phonenumber=13000000001 ,要求返回电话号码为 13000000001 客户记录。

我们可以通过 filter 方法加入过滤条件,修改view里面的代码,如下所示

def listcustomers(request):
    # 返回一个 QuerySet 对象 ,包含所有的表记录
    qs = Customer.objects.values()

    # 检查url中是否有参数phonenumber
    ph =  request.GET.get('phonenumber',None)

    # 如果有,添加过滤条件
    if ph:
        qs = qs.filter(phonenumber=ph)

    # 定义返回字符串
    retStr = ''
    for customer in  qs:
        for name,value in customer.items():
            retStr += f'{name} : {value} | '
        # <br> 表示换行
        retStr += '<br>'

    return HttpResponse(retStr)

看到函数定义的参数 request了吗?

Django 框架在 url 路由匹配到函数后, 调用函数时,会传入 一个 HttpRequest 对象给参数变量 request,该对象里面 包含了请求的数据信息。

HTTP 的 Get 请求url里面的参数(术语叫 querystring 里面的参数), 可以通过 HttpRequest对象的 GET 属性获取。这是一个类似dict的对象。

比如要获取querystring里面的 phonenumber 参数 ,就可以像这样

ph =  request.GET.get('phonenumber',None)

第二个参数传入 None 表示,如果没有 phonenumber 参数在 querystring中 ,就会返回 None。

然后通过调用 QuerySet 对象的filter方法,就可以把查询过滤条件加上去

qs = qs.filter(phonenumber=ph)

有了这个过滤条件,Django 会在底层执行数据库查询的SQL语句 加上相应的 where 从句,进行过滤查询。

注意,参数名 phonenumber 是和 定义的表 model 的属性名 phonenumber 一致的。

filter的过滤条件可以有多个,只要继续在后面的参数添加过滤条件即可。

比如

qs = qs.filter(phonenumber=ph,address='安徽芜湖')

这样就 除了 根据电话号码字段过滤,还有根据 地址字段过滤。

现在在浏览器输入如下 url

http://127.0.0.1/sales/customers/?phonenumber=13000000001

访问结果如下

image

可以发现过滤条件生效了。



目前为止,我们项目代码,在如下百度网盘中的 bysms_03.zip

百度网盘链接:https://pan.baidu.com/s/1nUyxvq6IYykBNtPUf4Ho6w 提取码:9w2u


作业和练习

根据课程内容,在现有项目代码的基础上,

加上对 sales/customers/ url请求的 路由。

并且自己写代码,处理这种路由的HTTP请求消息。

并且代码能够处理 url参数指定的两种查询条件:

根据 电话号码 和 根据 用户名 查询。

当用户在浏览器输入 /sales/customers/?phonenumber=13000000001&name=lihua ,要求返回电话号码为 13000000001 并且 用户名为 lihua 的 客户记录。

写好后,启动web服务。测试一下,在浏览器访问上面的 路由,检查 返回到浏览器中的信息是否正确。

补充学习 - 过滤条件

大于、小于

有时候,我们过滤条件不是某个字段的值等于什么,而是某个字段的值 大于小于大于等于小于等于 一个值

应该分别使用 过滤字段名加后缀 __gt__lt__gte__lte 。 注意里面的下划线有两个

比如,选择过滤项为 年龄 age 字段值, 如下所示

qs.filter(age__gt=35) # 大于 35 岁

qs.filter(age__lt=35) # 小于 35 岁

qs.filter(age__gte=35) # 大于等于 35 岁

qs.filter(age__lte=35) # 小于等于 35 岁

以什么开头、结尾,包含什么

如果过滤条件是某个字符串字段值 以什么开头 和什么结尾 , 比如 name 字段, 如下所示

qs.filter(name__startswith='Mike') #  以 Mike 开头, 大小写敏感

qs.filter(name__endswith='Green')  #  以 Green 结尾, 大小写敏感

qs.filter(name__contains='ee')     #  包含  ee , 大小写敏感

qs.filter(name__istartswith='Mike') #  以 Mike 开头, 忽略大小写

qs.filter(name__iendswith='Green')  #  以 Green 结尾, 忽略大小写

qs.filter(name__icontains='ee')    #  包含  ee , 忽略大小写

某些取值之一

如果过滤条件是 某个字符串字段值 为某些取值之一, 可以使用 __in 后缀,取值选项放入一个列表中, 如下所示

#  name 取值为 Mike、Jack、Jerry 任意之一,都可以
qs.filter(name__in=['Mike', 'Jack'、'Jerry']) 



更多字段过滤方式

更多字段过滤方式点击这里参考官方文档