第五步、商品首页

1、父模板和缓存的演示在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
2、首页的开发
在这里插入图片描述在这里插入图片描述在这里插入图片描述
index.html显示

{% extends 'base.html' %}
{% load static %}
{% load cache %}
{% block title %}天天生鲜-首页{% endblock %}

{% block topfiles %}
    <script type="text/javascript" src="{% static 'js/jquery-1.12.4.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'js/jquery-ui.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'js/slide.js' %}"></script>
{% endblock %}



{% cache 3600 body %}
{% block body %}


    <div class="navbar_con">
        <div class="navbar">
            <h1 class="fl">全部商品分类</h1>
            <ul class="navlist fl">
                <li><a href="{% url 'goods:index' %}">首页</a></li>
                <li class="interval">|</li>
                <li><a href="javascript:alert('待开发!');">手机生鲜</a></li>
                <li class="interval">|</li>
                <li><a href="javascript:alert('待开发!');">抽奖</a></li>
            </ul>
        </div>
    </div>

    <div class="center_con clearfix">
        <ul class="subnav fl">
            {% for type in types %}
                <li><a href="#model0{{ forloop.counter }}" class="{{ type.logo }}">{{ type.name }}</a></li>
            {% endfor %}
        </ul>
        <div class="slide fl">
            <ul class="slide_pics">
                {% for banner in GoodsBanner %}
                    <li><a href="{% url 'goods:detail' banner.sku.id %}"><img src="{{ banner.image.url }}" alt="幻灯片"></a></li>
                {% endfor %}

            </ul>
            <div class="prev"></div>
            <div class="next"></div>
            <ul class="points"></ul>
        </div>
        <div class="adv fl">
            {% for banner in PromotionBanner %}
                <a href="{{ banner.url }}"><img src="{{ banner.image.url }}" alt=""></a>
            {% endfor %}


        </div>
    </div>

    {% for type in types %}
        <div class="list_model">
            <div class="list_title clearfix">
                <h3 class="fl" id="model0{{ forloop.counter }}">{{ type.name }}</h3>
                <div class="subtitle fl">
                    <span>|</span>
                    {% for banner in type.tltle_banner %}
                        <a href="{% url 'goods:detail' banner.sku.id %}">{{ banner.sku.name }}</a>
                    {% endfor %}
                </div>
                <a href="{% url 'goods:list' type.id 1 %}" class="goods_more fr" id="fruit_more">查看更多 ></a>
            </div>

            <div class="goods_con clearfix">
                <div class="goods_banner fl"><img src="{{ type.image.url }}" alt=""></div>
                <ul class="goods_list fl">
                    {% for banner in type.img_banner %}
                        <li>
                            <h4><a href="#">{{ banner.sku.name }}</a></h4>
                            <a href="{% url 'goods:detail' banner.sku.id %}"><img src="{{ banner.sku.image.url }}" alt=""></a>
                            <div class="prize">¥ {{ banner.sku.price }}</div>
                        </li>
                    {% endfor %}
                </ul>
            </div>
        </div>
    {% endfor %}

{% endblock %}
{% endcache %}

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
detail.html显示

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

{% block main_content %}

    <div class="breadcrumb">
        <a href="{% url 'goods:index' %}">全部分类</a>
        <span>></span>
        <a href="{% url 'goods:index' %}">{{ sku.type.name }}</a>
        <span>></span>
        <a href="#">商品详情</a>
    </div>
    <div class="goods_detail_con clearfix">
        <div class="goods_detail_pic fl"><img src="{{ sku.image.url }}" alt=""></div>

        <div class="goods_detail_list fr">
            <h3>{{ sku.name }}</h3>
            <p>{{ sku.desc }}</p>
            <div class="prize_bar">
                <span class="show_pirze">¥<em>{{ sku.price }}</em></span>
                <span class="show_unit">单  位:{{ sku.unite }}</span>
            </div>
            <div class="goods_num clearfix">
                <div class="num_name fl">数 量:</div>
                <div class="num_add fl">
                    <input type="text" class="num_show fl" value="1">
                    <a href="javascript:;" class="add fr">+</a>
                    <a href="javascript:;" class="minus fr">-</a>
                </div>
            </div>
            <div>
                <p>其他规格:</p>
                <ul>
                    {% for sku in same_spu_skus %}
                        <li><a href="{% url 'goods:detail' sku.id %}">{{ sku.name }}</a></li>
                    {% endfor %}
                </ul>

            </div>


            <div class="total">总价:<em>16.80</em></div>
            <div class="operate_btn">
                <a href="javascript:;" class="buy_btn">立即购买</a>
                <a href="javascript:;" sku_id="{{ sku.id }}" class="add_cart" id="add_cart">加入购物车</a>
            </div>
        </div>
    </div>

    <div class="main_wrap clearfix">
        <div class="l_wrap fl clearfix">
            <div class="new_goods">
                <h3>新品推荐</h3>
                <ul>
                    {% for sku in new_skus %}
                        <li>
                            <a href="{% url 'goods:detail' sku.id %}"><img src="{{ sku.image.url }}" alt=""></a>
                            <h4><a href="#">{{ sku.name }}</a></h4>
                            <div class="prize">{{ sku.price }}</div>
                        </li>
                    {% endfor %}
                </ul>
            </div>
        </div>

        <div class="r_wrap fr clearfix">
            <ul class="detail_tab clearfix">
                <li class="active">商品介绍</li>
                <li>评论</li>
            </ul>

            <div class="tab_content">
                <dl>
                    <dt>商品详情:</dt>
                    <dd>{{ sku.goods.detail|safe }}
                    </dd>
                </dl>
            </div>
            <div class="tab_content">
                <dl>
                    {% for order in sku_order %}
                        <dt>评论时间:{{ order.update_time }}&nbsp;&nbsp;用户名:{{ order.order.user.username }}</dt>
                        <dd>评论内容:{{ order.comment }}</dd>
                    {% endfor %}
                </dl>
            </div>
        </div>
    </div>
{% endblock %}

{% block bottom %}
    <div class="add_jump"></div>
    {% csrf_token %}
{% endblock %}
{% block bottomfiles %}
    <script type="text/javascript" src="{% static 'js/jquery-1.12.4.min.js' %}"></script>
    <script type="text/javascript">
        update_goods_amount();
        function update_goods_amount() {
            // 获取商品的数量和价格
            var price = $('.show_pirze').children('em').text();
            var count = $('.num_show').val();
            // 计算商品的总价
            price = parseFloat(price);
            count = parseInt(count);
            var amount = price * count;
            $('.total').children('em').text(amount.toFixed(2) + '元');

        }

        // 增加商品的数量
        $('.add').click(function () {
            // 获取商品原油的数目
            var count = $('.num_show').val();
            count = parseInt(count) + 1;
            $('.num_show').val(count);
            update_goods_amount();
        });


        // 减少商品的数量
        $('.minus').click(function () {
            // 获取商品原油的数目
            var count = $('.num_show').val();
            count = parseInt(count) - 1;
            if (count <= 0) {
                count = 1;
            }

            $('.num_show').val(count);
            update_goods_amount();
        });

        // 手动输入商品的数量
        $('.num_show').blur(function () {
            // 获取商品原油的数目
            var count = $(this).val();
            // 校验count是否合法
            if (isNaN(count) || count.trim().length == 0 || parseInt(count) <= 0) {
                count = 1
            }
            // 重新设置商品的数目
            $(this).val(parseInt(count));
            update_goods_amount();
        });

        // 获取add_cart div元素左上角坐标
        var $add_x = $('#add_cart').offset().top;
        var $add_y = $('#add_cart').offset().left;

        // 获取show_count div元素左上角坐标
        var $to_x = $('#show_count').offset().top;
        var $to_y = $('#show_count').offset().left;


        $('#add_cart').click(function () {
            // 获取商品的id和数量
            var sku_id = $(this).attr('sku_id');
            var count = $('.num_show').val();
            var scrf = $('input[name="csrfmiddlewaretoken"]').val();

            // 发起请求
            $.ajax({
                type: 'post',
                url: "{% url 'cart:add' %}",
                data: {
                    sku_id: sku_id,
                    count: count,
                    csrfmiddlewaretoken: scrf,
                },
                success: function (data) {
                    if (data.res === 5) {
                        $(".add_jump").css({'left': $add_y + 80, 'top': $add_x + 10, 'display': 'block'});
                        $(".add_jump").stop().animate({
                                'left': $to_y + 7,
                                'top': $to_x + 7
                            },
                            "fast", function () {
                                $(".add_jump").fadeOut('fast', function () {
                                    $('#show_count').html(data.total_count);
                                });
                            });
                    } else {
                        alert(data.errmsg)
                    }
                }
            });
        })
    </script>
{% endblock %}

在这里插入图片描述在这里插入图片描述
list.html显示

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

{% block main_content %}

    <div class="breadcrumb">
        <a href="#">全部分类</a>
        <span>></span>
        <a href="#">{{ type.name }}</a>
    </div>

    <div class="main_wrap clearfix">
        <div class="l_wrap fl clearfix">
            <div class="new_goods">
                <h3>新品推荐</h3>
                <ul>
                    {% for sku in new_skus %}
                        <li>
                            <a href="{% url 'goods:detail' sku.id %}"><img src="{{ sku.image.url }}" alt=""></a>
                            <h4><a href="{% url 'goods:detail' sku.id %}">{{ sku.name }}</a></h4>
                            <div class="prize">{{ sku.price }}</div>
                        </li>
                    {% endfor %}
                </ul>
            </div>
        </div>

        <div class="r_wrap fr clearfix">
            <div class="sort_bar">
                <a href="{% url 'goods:list' type.id 1 %}" {% if sort == 'default' %}class="active" {% endif %}>默认</a>
                <a href="{% url 'goods:list' type.id 1 %}?sort=price" {% if sort == 'price' %}class="active" {% endif %}>价格</a>
                <a href="{% url 'goods:list' type.id 1 %}?sort=hot" {% if sort == 'hot' %}class="active" {% endif %} >人气</a>
            </div>

            <ul class="goods_type_list clearfix">
                {% for sku in skus_page %}

                    <li>
                        <a href="{% url 'goods:detail' sku.id %}"><img src="{{ sku.image.url }}"></a>
                        <h4><a href="{% url 'goods:detail' sku.id %}">大兴大棚草莓</a></h4>
                        <div class="operate">
                            <span class="prize">{{ sku.price }}</span>
                            <span class="unit">{{ sku.price }}/{{ sku.unite }}</span>
                            <a href="{% url 'goods:detail' sku.id %}" class="add_goods" title="加入购物车"></a>
                        </div>
                    </li>
                {% endfor %}


            </ul>

            <div class="pagenation">
                {% if skus_page.has_previous %}
                    <a href="{% url 'goods:list' type.id skus_page.previous_page_number %}?sort={{ sort }}">上一页</a>
                {% endif %}
                {% for page in skus_page.paginator.page_range %}
                    {% if page == skus_page.number %}
                        <a href="{% url 'goods:list' type.id page %}" class="active">{{ page }}</a>
                    {% else %}
                        <a href="{% url 'goods:list' type.id page %}">{{ page }}</a>
                    {% endif %}
                {% endfor %}
                {% if skus_page.has_next %}
                    <a href="{% url 'goods:list' type.id skus_page.next_page_number %}?sort={{ sort }}">下一页></a>
                {% endif %}
            </div>
        </div>
    </div>
{% endblock %}

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

search.html显示

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

{% block main_content %}

    <div class="breadcrumb">
        <a href="#">{{ query }}</a>
        <span>></span>
        <a href="#">搜索结果如下:</a>
    </div>

    <div class="main_wrap clearfix">


        <ul class="goods_type_list clearfix">
            {% for item in page %}

                <li>
                    <a href="{% url 'goods:detail' item.object.id %}"><img src="{{ item.object.image.url }}"></a>
                    <h4><a href="{% url 'goods:detail' item.object.id %}">{{ item.object.name }}</a></h4>
                    <div class="operate">
                        <span class="prize">{{ item.object.price }}</span>
                        <span class="unit">{{ item.object.price }}/{{ sku.unite }}</span>
                        <a href="{% url 'goods:detail' item.object.id %}" class="add_goods" title="加入购物车"></a>
                    </div>
                </li>
            {% endfor %}
        </ul>

{#        <div class="pagenation">#}
{#            {% if skus_page.has_previous %}#}
{#                <a href="{% url 'goods:list' type.id skus_page.previous_page_number %}?sort={{ sort }}">上一页</a>#}
{#            {% endif %}#}
{#            {% for page in skus_page.paginator.page_range %}#}
{#                {% if page == skus_page.number %}#}
{#                    <a href="{% url 'goods:list' type.id page %}" class="active">{{ page }}</a>#}
{#                {% else %}#}
{#                    <a href="{% url 'goods:list' type.id page %}">{{ page }}</a>#}
{#                {% endif %}#}
{#            {% endfor %}#}
{#            {% if skus_page.has_next %}#}
{#                <a href="{% url 'goods:list' type.id skus_page.next_page_number %}?sort={{ sort }}">下一页></a>#}
{#            {% endif %}#}
{#        </div>#}
    </div>

{% endblock %}

base.py编写
在这里插入图片描述

from django.db import models


class BaseModel(models.Model):
    '''模型抽象基类'''
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    update_time = models.DateTimeField(auto_now_add=True, verbose_name='更新时间')
    delflag = models.BooleanField(default=False, verbose_name='删除标识')

    class Meta:
        abstract = True

在这里插入图片描述
goods.views.py编写

from django.shortcuts import render, redirect, reverse
from django.core.paginator import Paginator
from django.views import View
from goods.models import *
from order.models import OrderGoods
from django_redis import get_redis_connection


# Create your views here.


class IndexView(View):

    def get(self, request):
        # 获取商品种类
        types =     GoodsType.objects.all()
        # 获取首页轮播商品信息
        GoodsBanner = IndexGoodsBanner.objects.all().order_by('index')
        # 获取首页活动信息
        PromotionBanner = IndexPromotionBanner.objects.all().order_by('index')
        # 获取首页分类商品展示信息
        for type in types:
            type.img_banner = IndexTypeGoodsBanner.objects.filter(
                type=type, display_type=1).order_by('index')
            type.tltle_banner = IndexTypeGoodsBanner.objects.filter(
                type=type, display_type=0).order_by('index')

        # 获取购物车商品数量
        cart_count = 0
        if request.user.is_authenticated:
            coon = get_redis_connection('default')
            cart_key = 'cart_%d' % request.user.id
            cart_count = coon.hlen(cart_key)

        # 模板上下文
        context = {
            'types': types,
            'GoodsBanner': GoodsBanner,
            'PromotionBanner': PromotionBanner,
            'cart_count': cart_count,
        }

        return render(request, 'index.html', context)


class DetailView(View):
    def get(self, request, pk):
        # 查询商品id是否存在
        try:
            sku = GoodsSKU.objects.get(pk=pk)
        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')[0:2]

        # 获取同一商品spu的其他规格商品
        same_spu_skus = GoodsSKU.objects.filter(goods=sku.goods).exclude(pk=pk)

        # 获取购物车商品数量
        cart_count = 0
        if request.user.is_authenticated:
            coon = get_redis_connection('default')
            cart_key = 'cart_%d' % request.user.id
            cart_count = coon.hlen(cart_key)

            # 添加用户的历史浏览记录
            coon = get_redis_connection('default')
            history_key = 'history_%d' % request.user.id
            # 移除之前的该商品id
            coon.lrem(history_key, 0, pk)
            # 把goods_id左侧插入redis列表
            coon.lpush(history_key, pk)
            # 取用户保存的最新5条信息
            coon.ltrim(history_key, 0, 4)

        context = {
            'sku': sku,
            'types': types,
            'sku_order': sku_orders,
            'new_skus': new_skus,
            'cart_count': cart_count,
            'same_spu_skus': same_spu_skus
        }

        return render(request, 'detail.html', context)


class ListView(View):
    def get(self, request, type_id, page):
        # 获取种类信息
        try:
            type = GoodsType.objects.get(pk=type_id)
        except GoodsType.DoesNotExist:
            return redirect(reverse('goods:index'))

        types = GoodsType.objects.all()

        sort = request.GET.get('sort', 'default')
        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:
            skus = GoodsSKU.objects.filter(type=type).order_by('-id')

        paginator = Paginator(skus, 8)

        # 对页码进行容错处理
        try:
            page = int(page)
        except Exception:
            page = 1

        if page > paginator.num_pages:
            page = paginator.num_pages

        skus_page = paginator.page(page)

        # todo 页码的控制
        # 1 当总页数小于5页,页面上显示所有页面
        # 2 如果当前页是前三页  显示前5页的页码
        # 3 如果当前页是后三页码  显示后5页
        # 4 其他情况  显示当前页的前两页  当前页  当前页的后两页
        num_pages = paginator.num_pages
        if num_pages < 5:
            pages = range(1, num_pages + 1)
        elif page <= 3:
            pages = range(1, 6)
        elif num_pages - page <= 2:
            pages = range(num_pages - 4, num_pages + 1)
        else:
            pages = range(page - 2, page + 3)

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

        # 获取购物车商品数量
        cart_count = 0
        if request.user.is_authenticated:
            coon = get_redis_connection('default')
            cart_key = 'cart_%d' % request.user.id
            cart_count = coon.hlen(cart_key)

        context = {
            'type': type,
            'types': types,
            'skus_page': skus_page,
            'new_skus': new_skus,
            'cart_count': cart_count,
            'sort': sort,
            'pages': pages
        }

        return render(request, 'list.html', context)

search_index.py编写

# 定义索引类
from haystack import indexes
from goods.models import GoodsSKU


class GoodsSKUIndex(indexes.SearchIndex, indexes.Indexable):
    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()

在这里插入图片描述
admin.py编写

from django.contrib import admin
from goods.models import *
# Register your models here.

admin.site.register(GoodsType)
admin.site.register(GoodsSKU)
admin.site.register(Goods)
admin.site.register(GoodsImage)
admin.site.register(IndexGoodsBanner)
admin.site.register(IndexTypeGoodsBanner)
admin.site.register(IndexPromotionBanner)

admins.py编写

import xadmin
from .models import *


class GoodsTypeAdmin(object):
    list_display = ['id', 'name', 'logo', 'image']
    list_display_links = ['id', 'name']
    search_fields = ['name', 'create_time', 'update_time']
    list_filter = ['create_time', 'update_time', 'delflag']


class GoodsSKUAdmin(object):
    list_display = ['id', 'name', 'detail']
    list_display_links = ['id', 'name']
    search_fields = ['name', 'create_time', 'update_time']
    list_filter = ['create_time', 'update_time', 'delflag']

class GoodsAdmin(object):
    list_display = ['id', 'type', 'goods', 'name', 'price', 'unite']
    list_display_links = ['id', 'name']
    search_fields = ['name', 'create_time', 'update_time']
    list_filter = ['create_time', 'update_time', 'delflag']

class GoodsImageAdmin(object):
    list_display = ['id', 'sku', 'image']
    list_display_links = ['id', 'sku']
    search_fields = ['name', 'create_time', 'update_time']
    list_filter = ['create_time', 'update_time', 'delflag']


xadmin.site.register(GoodsType, GoodsTypeAdmin)
xadmin.site.register(GoodsSKU, GoodsSKUAdmin)
xadmin.site.register(Goods, GoodsSKUAdmin)
xadmin.site.register(GoodsImage, GoodsImageAdmin)
xadmin.site.register(IndexGoodsBanner)
xadmin.site.register(IndexTypeGoodsBanner)
xadmin.site.register(IndexPromotionBanner)

在这里插入图片描述
urls.py编写

扫描二维码关注公众号,回复: 11515357 查看本文章
from django.urls import path, re_path
from . import views


app_name = 'goods'

urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
    re_path(r'^goods/(?P<pk>\d+)$', views.DetailView.as_view(), name='detail'),
    re_path(r'^list/(?P<type_id>\d+)/(?P<page>\d+)$', views.ListView.as_view(), name='list')
]

猜你喜欢

转载自blog.csdn.net/qq_42611683/article/details/107374270
今日推荐