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

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

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

这一篇教程,我们继续完成商品列表的删除和价格区间查询功能。

二、完成删除商品并从列表中移除的功能

当我们点击商品列表中任意一条商品信息后方的删除按钮,都能够将该条商品信息从商品列表中删除。

1、模板中添加JavaScript脚本代码

示例代码:

$('button.delete').click(function () {
    var name = $(this).attr('id');
    $.getJSON("/del/", {'goods_name': name}, function (result) {
        if (result === 200) {
            location.reload()
        }
    })
});

在上方代码中,第一行的语句表示这是一个页面中所有“class”属性为“delete”的“botton”标签,在被点击(click)时,执行的脚本函数(function)。

第二句代码是创建了一个变量,获取当前(this)被点击标签的“id”属性值(attr)。

当获取到当前被点击按钮的“id”属性值(还记得吗?是商品名称),就可以通过“getJSON()”向服务器发起请求。

2、配置URL分发

示例代码:

path('del/', siteviews.delete),

3、定义视图函数

示例代码:

def delete(request):
    goods_name = request.GET['goods_name']
    goods = Goods.objects.filter(goods_name=goods_name)
    try:
        goods.delete()
        result = 200
    except:
        result = 100
    return HttpResponse(result)

三、完成价格区间查询功能

当我们输入查询商品的最小价格和最大价格,点击确定按钮之后,页面中展示筛选后的商品列表。

1、定义视图函数

为了更好理解视图和JS之间数据的传输,我们先来完成视图函数的定义。

示例代码:

from django.core import serializers
def search(request):
    min_price = int(request.GET['min_price'])
    max_price = int(request.GET['max_price'])
    goods = Goods.objects.filter(goods_price__gte=min_price, goods_price__lte=max_price)
    try:
        if goods:
            result = json.dumps(serializers.serialize('json', goods))
        else:
            result = 100
    except:
        result = 100
    print(result)
    return HttpResponse(result)

在上方代码中,我们依据最小价格和最大价格进行数据库查询,如果未查询到结果或者发生异常,都返回错误的编号,否则返回一个经过序列化和格式化的结果。

其中,“serializers.serialize(‘json’, goods)”是将查询结果(QuerySet类型)序列化为JSON格式的字典。

而“json.dumps()”则是将字典序列化为JSON格式的字符串。

通过这两次序列化,我们就能够在JS中获取到查询结果的数据。

2、配置URL分发

path('search/', siteviews.search),

3、模板中添加JavaScript脚本代码

示例代码:

$('#search').click(function () {
    $('#list').empty();
    var min_price = $('#min_price').val();
    var max_price = $('#max_price').val();
    $.getJSON("/search/", {
        'min_price': min_price,
        'max_price': max_price
    }, function (result) {
        var labels = '';
        if (result === 100) {
            labels = '<label>没有查询结果!</label>';
        } else {
            var data = JSON.parse(result);
            for (i in data) {
                labels += '<div id="' + data[i]['pk'] + '">';
                labels += '<label style="display:inline-block;width:125px;">名称:' + data[i]['pk'] + '</label>' +
                    '<label style="display:inline-block;width:95px;">数量:' + data[i]['fields']['goods_number'] + '</label>' +
                    '<label style="display:inline-block;width:95px;">价格:' + data[i]['fields']['goods_price'] + '</label>' +
                    '<button class="delete" type="button" id="' + data[i]['pk'] + '">删除</button><br>';
                labels += '</div>';
            }
        }
        $('#list').append(labels)
    })
});

在上方代码中,有一些需要注意的地方:

(1)第二句代码“$(‘#list’).empty();”,表示将“id”属性值为“list”的元素所包含的子元素清空,即清空商品列表。

(2)变量“labels”负责组织一条商品信息包含的HTML代码,并且在这些代码中动态的嵌入服务器返回的数据。

(3)变量“data”保存通过“JSON.parse()”解析“result”数据后得到的JSON对象。

(4)使用“for”循环对“data”进行遍历,并生成每一条商品信息的HTML代码。

(5)我们从服务器获取到的一条商品数据类似“{“model”: “MySite.goods”, “pk”: “\u81ea\u52a8\u7b14\u82af”, “fields”: {“goods_number”: 36, “goods_price”: 2.1, “goods_sales”: 0}}”的格式,由模型、主键和字段3个部分组成,我们要获取到主键的值和各个字段的值添加到每条商品信息的HTML代码中 。主键是商品名,通过“data[i][‘pk’]”获取,其他商品信息则通过“data[i][‘fields’][‘字段名称’]”获取。

(6)当所有的商品信息的HTML代码全部生成,通过“ $(‘#list’).append(labels)”添加到“id”属性为“list”的元素中,即形成新的商品列表。

提示,在浏览器中通过JS加载的商品信息可能会出现宽度发生改变,例如上方JS脚本代码中的每个“label”标签的宽度都增加了5px。

四、删除的再次实现。

为什么要再次实现呢?

大家在进行价格区间的查询之后会发现,点击删除按钮没有任何反应。

这是因为这些查询后的商品信息是通过JS动态加载的,而不是页面上原有的HTML代码。

那么,如何让删除按钮生效,在点击的时候能够向服务器发起删除的请求,并将页面中相应的商品信息删除呢?

我们可以使用on()函数重写删除的JS代码。

示例代码:

$(document).on('click', 'button.delete', function () {
    var name = $(this).attr('id');
    $.getJSON("/del/", {'goods_name': name}, function (result) {
        if (result === 200) {
            $('div').remove('#' + name);
            {#$('#' + name).remove();#}{#也可以使用这一句#}
        }
    })
});

在上方代码中,第一句会让页面文档(document)中,所有“class”属性值为“delete”的“button”标签被点击(on click)时,执行函数(function)的语句块。

语句块中,变量“name”保存获取到的当前(this)标签的“id”属性值(attr);然后,当服务器返回成功的编号时,从所有“div”标签中移除“id”属性值与变量name相同的子元素。

提示:也可以像注释({##})中一样,写成“ $(‘#’ + name).remove();”,即将页面中所有“id”属性值与变量name相同的元素移除。

注意,这里不要用“location.reload()”,不仅仅是因为会再次向服务器发出请求,而是这样做的话商品列表中会显示所有商品信息,不再是查询结果删除某一项后剩余的商品信息。

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

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

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

表情

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

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

网友最新评论 (11)

  1. 头像
    三、完成价格区间查询功能 代码肯定有问题。楼主你能看一下吗? serializers未定义
    走路爱走神1年前 (2018-06-05)回复
    • 头像
      from django.core import serializers
      大飞1年前 (2018-06-21)回复
  2. 头像
    结果也跑不出来 ➡
    走路爱走神1年前 (2018-06-05)回复
  3. 头像
    看了一下源码,忘记导包了_(:з」∠)_
    走路爱走神1年前 (2018-06-05)回复
  4. 头像
    代码还是有问题,但是对学习的人问题不大。 labels += '名称:' + data[i]['pk'] + '' + 名称出来的一定是数字,例如 "名称:3 数量5 价格2"。 而不会是 "名称:三角尺 数量5 价格2"。
    走路爱走神1年前 (2018-06-05)回复
    • 小楼一夜听春语
      忘记说了,数据模型中商品名称是主键,正文中已修正,见第一部分第1点。
      小楼一夜听春语1年前 (2018-06-07)回复
      • 头像
        Web项目开发入门笔记(10)定义的是GoodsInfo,在10、11中一直使用Goods,因此才会出现data[i]['pk']显示数字问题;1)把GoodsInfo修改为Goods;2)或者把data[i]['pk'] 修改为data[i]['fields']['goods_name'],谢谢楼主的付出!
        Eric Hoo9个月前 (01-02)回复
      • 头像
        0.0我看都是九月份之前已修正,但是,我现在看网页上,为什么还是没变?现在还是 data[i]['pk']
        大可爱6个月前 (03-15)回复
        • 小楼一夜听春语
          正文中已修正,见第一部分(第10篇)第1点。
          小楼一夜听春语6个月前 (03-18)回复
  5. 头像
    "[ {\"model\": \"MySite.goodsinfo\", \"pk\": 5, \"fields\": {\"goods_name\": \"\\u7b14\\u8bb0\\u672c\", \"goods_number\": 21, \"goods_price\": 6.2}}, {\"model\": \"MySite.goodsinfo\", \"pk\": 8, \"fields\": {\"goods_name\": \"\\u58a8\\u6c34\", \"goods_number\": 12, \"goods_price\": 5.0}}, {\"model\": \"MySite.goodsinfo\", \"pk\": 13, \"fields\": {\"goods_name\": \"\\u7b7e\\u5b57\\u7b14\", \"goods_number\": 20, \"goods_price\": 6.8}} ]"
    走路爱走神1年前 (2018-06-05)回复
  6. 头像
    谢谢楼主分享,已学习,嘿嘿^^
    走路爱走神1年前 (2018-06-05)回复