栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Django电商项目(六)商品详情页、列表页分页、商品搜索

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Django电商项目(六)商品详情页、列表页分页、商品搜索

Django电商项目
  • 商品详情页
  • 商品列表页
  • 商品搜索
    • 全文检索
    • 安装和配置
    • 索引文件生成
    • 全文检索的使用
    • 改变分词方式

商品详情页

新建detail.html

{% extends 'base_detail_list.html' %}
{% block title %}天天生鲜-商品详情{% endblock title %}

{% block main_content %}
	

	

{{ sku.name }}

{{ sku.desc }}

¥{{ sku.price }} 单 位:{{ sku.unite }}
数 量:
+ -

其他规格:

总价:16.80元

新品推荐

    {% for sku in new_skus %}
  • {{ sku.name }}

    ¥{{ sku.price }}
  • {% endfor %}
  • 商品介绍
  • 评论
商品详情:
{{ sku.goods.detail|safe }}
{% for order in sku_orders %}
评论时间:{{ order.update_time }}  用户名:{{ order.order.user.username }}
评论内容:{{ order.comment }}
{% endfor %}
{% endblock main_content %} {% block bottom %}
{% endblock bottom %} {% block bottomfiles %} {% endblock bottomfiles %}

view.py

# /goods/商品id
class DetailView(View):
    '''详情页'''
    def get(self, request, goods_id):
        '''显示详情页'''
        try:
            sku = GoodsSKU.objects.get(id=goods_id)
        except GoodsSKU.DoesNotExist:
            # 商品不存在
            return redirect(reverse('goods:index'))

        # 获取商品的分类信息
        types = GoodsType.objects.all()

        # 获取商品的评论信息
        sku_orders = OrderGoods.objects.filter(sku=sku).exclude(comment='')

        # 获取新品信息
        new_skus = GoodsSKU.objects.filter(type=sku.type).order_by('-create_time')[:2]

        # 获取同一个SPU的其他规格商品
        same_spu_skus = GoodsSKU.objects.filter(goods=sku.goods).exclude(id=goods_id)

        # 获取用户购物车中商品的数目
        user = request.user
        cart_count = 0
        if user.is_authenticated():
            # 用户已登录
            conn = get_redis_connection('default')
            cart_key = 'cart_%d' % user.id
            cart_count = conn.hlen(cart_key)

            # 添加用户的历史记录
            conn = get_redis_connection('default')
            history_key = 'history_%d'%user.id
            # 移除列表中的goods_id
            conn.lrem(history_key, 0, goods_id)
            # 把goods_id插入到列表的左侧
            conn.lpush(history_key, goods_id)
            # 只保存用户最新浏览的5条信息
            conn.ltrim(history_key, 0, 4)

        # 组织模板上下文
        context = {'sku':sku, 'types':types,
                   'sku_orders':sku_orders,
                   'new_skus':new_skus,
                   'same_spu_skus':same_spu_skus,
                   'cart_count':cart_count}

        # 使用模板
        return render(request, 'detail.html', context)

商品列表页

修改list.html文件

{% extends 'base_detail_list.html' %}
{% block title %}天天生鲜-商品列表{% endblock title %}
{% block main_content %}
	

	

新品推荐

    {% for sku in new_skus %}
  • {{ sku.name }}

    ¥{{ sku.price }}
  • {% endfor %}
默认 价格 人气
    {% for sku in skus_page %}
  • {{ sku.name }}

    ¥{{ sku.price }} {{ sku.price}}/{{ sku.unite }}
  • {% endfor %}
{% if skus_page.has_previous %} <上一页 {% endif %} {% for pindex in skus_page.paginator.page_range %} {% if pindex == skus_page.number %} {{ pindex }} {% else %} {{ pindex }} {% endif %} {% endfor %} {% if skus_page.has_next %} 下一页> {% endif %}
{% endblock main_content %}

定义view.py
分页导入
from django.core.paginator import Paginator
分页参考文档
https://doc.codingdict.com/django/topics/pagination.html

# 种类id 页码 排序方式
# restful api -> 请求一种资源
# /list?type_id=种类id&page=页码&sort=排序方式
# /list/种类id/页码/排序方式
# /list/种类id/页码?sort=排序方式
class ListView(View):
    '''列表页'''
    def get(self, request, type_id, page):
        '''显示列表页'''
        # 获取种类信息
        try:
            type = GoodsType.objects.get(id=type_id)
        except GoodsType.DoesNotExist:
            # 种类不存在
            return redirect(reverse('goods:index'))

        # 获取商品的分类信息
        types = GoodsType.objects.all()

        # 获取排序的方式 # 获取分类商品的信息
        # sort=default 按照默认id排序
        # sort=price 按照商品价格排序
        # sort=hot 按照商品销量排序
        sort = request.GET.get('sort')

        if sort == 'price':
            skus = GoodsSKU.objects.filter(type=type).order_by('price')
        elif sort == 'hot':
            skus = GoodsSKU.objects.filter(type=type).order_by('-sales')
        else:
            sort = 'default'
            skus = GoodsSKU.objects.filter(type=type).order_by('-id')

        # 对数据进行分页
        paginator = Paginator(skus, 1)

        # 获取第page页的内容
        try:
            page = int(page)
        except Exception as e:
            page = 1

        if page > paginator.num_pages:
            page = 1

        # 获取第page页的Page实例对象
        skus_page = paginator.page(page)

        # todo: 进行页码的控制,页面上最多显示5个页码

        # 获取新品信息
        new_skus = GoodsSKU.objects.filter(type=type).order_by('-create_time')[:2]

        # 获取用户购物车中商品的数目
        user = request.user
        cart_count = 0
        if user.is_authenticated():
            # 用户已登录
            conn = get_redis_connection('default')
            cart_key = 'cart_%d' % user.id
            cart_count = conn.hlen(cart_key)

        # 组织模板上下文
        context = {'type':type, 'types':types,
                   'skus_page':skus_page,
                   'new_skus':new_skus,
                   'cart_count':cart_count,
                   'sort':sort}

        # 使用模板
        return render(request, 'list.html', context)

配置url

url(r'^list/(?Pd+)/(?Pd+)$', ListView.as_view(), name='list'), # 列表页
商品搜索

全文检索

全文检索不同于特定字段的模糊查询,使用全文检索的效率更高,并且能够对于中文进行分词处理。

haystack:全文检索的框架,支持whoosh、solr、Xapian、Elasticsearc四种全文检索引擎,点击查看官方网站。
whoosh:纯Python编写的全文搜索引擎,虽然性能比不上sphinx、xapian、Elasticsearc等,但是无二进制包,程序不会莫名其妙的崩溃,对于小型的站点,whoosh已经足够使用,点击查看whoosh文档。
jieba:一款免费的中文分词包,如果觉得不好用可以使用一些收费产品。

安装和配置
  1. 安装python包。
    pip install django-haystack
    pip install whoosh
  2. 在settings.py文件中注册应用haystack并做如下配置。
# 全文检索框架的配置
HAYSTACK_ConNECTIONS = {
    'default': {
        # 使用whoosh引擎
        # 'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
        'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',
        # 索引文件路径
        'PATH': os.path.join(base_DIR, 'whoosh_index'),
    }
}

# 当添加、修改、删除数据时,自动生成索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

# 指定搜索结果每页显示的条数
HAYSTACK_SEARCH_RESULTS_PER_PAGE=1

索引文件生成
  1. 在goods应用目录下新建一个search_indexes.py文件,在其中定义一个商品索引类。
# 定义索引类
from haystack import indexes
# 导入你的模型类
from goods.models import GoodsSKU


# 指定对于某个类的某些数据建立索引
# 索引类名格式:模型类名+Index
class GoodsSKUIndex(indexes.SearchIndex, indexes.Indexable):
    # 索引字段 use_template=True指定根据表中的哪些字段建立索引文件的说明放在一个文件中
    text = indexes.CharField(document=True, use_template=True)

    def get_model(self):
        # 返回你的模型类
        return GoodsSKU

    # 建立索引的数据
    def index_queryset(self, using=None):
        return self.get_model().objects.all()

  1. 在templates下面新建目录search/indexes/goods
    goods文件名为索引的类在的应用的名字

  2. 在此目录下面新建一个文件goodssku_text.txt并编辑内容如下。
    命名规则:模型类名小写_text.txt

# 指定根据表中的哪些字段建立索引数据
{{ object.name }} # 根据商品的名称建立索引
{{ object.desc }} # 根据商品的简介建立索引
{{ object.goods.detail }} # 根据商品的详情建立索引
  1. 使用命令生成索引文件。
    python manage.py rebuild_index
全文检索的使用
  1. 配置url
    项目的url.py

2)表单搜索时设置表单内容如下。

点击标题进行提交时,会通过haystack搜索数据。

  1. 全文检索结果。
    搜索出结果后,haystack会把搜索出的结果传递给templates/search目录下的search.html,传递的上下文包括:
    query:搜索关键字
    page:当前页的page对象 –>遍历page对象,获取到的是SearchResult类的实例对象,对象的属性object才是模型类的对象。
    paginator:分页paginator对象

    通过HAYSTACK_SEARCH_RESULTS_PER_PAGE 可以控制每页显示数量。
    默认20条

创建search.html

{% extends 'base_detail_list.html' %}
{% block title %}天天生鲜-商品搜索结果列表{% endblock title %}
{% block main_content %}
	

	
    {% for item in page %}
  • {{ item.object.name }}

    ¥{{ item.object.price }} {{ item.object.price}}/{{ item.object.unite }}
  • {% endfor %}
{% if page.has_previous %} <上一页 {% endif %} {% for pindex in paginator.page_range %} {% if pindex == page.number %} {{ pindex }} {% else %} {{ pindex }} {% endif %} {% endfor %} {% if spage.has_next %} 下一页> {% endif %}
{% endblock main_content %}
改变分词方式

  1. 安装jieba分词模块。
    pip install jieba
  2. 找到虚拟环境py_django下的haystack目录。
    /home/python/.virtualenvs/bj17_py3/lib/python3.5/site-packages/haystack/backends/
  3. 在上面的目录中创建ChineseAnalyzer.py文件。
import jieba
from whoosh.analysis import Tokenizer, Token

class ChineseTokenizer(Tokenizer):
    def __call__(self, value, positions=False, chars=False,
                 keeporiginal=False, removestops=True,
                 start_pos=0, start_char=0, mode='', **kwargs):
        t = Token(positions, chars, removestops=removestops, mode=mode, **kwargs)
        seglist = jieba.cut(value, cut_all=True)
        for w in seglist:
            t.original = t.text = w
            t.boost = 1.0
            if positions:
                t.pos = start_pos + value.find(w)
            if chars:
                t.startchar = start_char + value.find(w)
                t.endchar = start_char + value.find(w) + len(w)
            yield t

def ChineseAnalyzer():
    return ChineseTokenizer()
  1. 复制whoosh_backend.py文件,改为如下名称。
    whoosh_cn_backend.py

  2. 打开复制出来的新文件,引入中文分析类,内部采用jieba分词。
    from .ChineseAnalyzer import ChineseAnalyzer

  3. 更改词语分析类。
    查找
    analyzer=StemmingAnalyzer()
    改为
    analyzer=ChineseAnalyzer()

  4. 修改settings.py文件中的配置项。

  5. 重新创建索引数据
    python manage.py rebuild_index

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/314145.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号