第1步:定义获取商品列表的视图类ListView,本视图中完成了如下功能:
- 根据商品类别id获取商品类别信息,并根据类别信息反向查询到所有的该类别的商品。
- 根据页号和排序方式两个参数,获取某个页面的商品列表信息。
#goods应用下views.pyfrom django.core.paginator import Paginator, EmptyPage
from django.http import HttpResponseNotFound, HttpResponseForbidden, JsonResponse
from django.shortcuts import render
from django.views import Viewfrom contents.utils import get_categories
from goods.models import GoodsCategory, SKU
from orders.models import OrderGoods
from xiaoyu_mall_new import settings
from xiaoyu_mall_new.utils.response_code import RETCODE
from .constants import PER_PRODUCTS_LIMIT as per_goods_num
from .utils import get_breadcrumbclass ListView(View):def get(self, request, category_id, page_num):"""提供商品列表页,category_id:商品类别idpage_num:第几页,页号"""try:# 1 根据商品类别id获取该商品类别category = GoodsCategory.objects.get(id=category_id)except GoodsCategory.DoesNotExist:return HttpResponseNotFound('"参数category_id不存在"')# 2 接收sort参数,如果没有传递这个参数,那么使用默认的排序方式。分别对应html页面中的默认、人气和价格3种排序方式sort = request.GET.get('sort', 'default')# 默认排序 按价格排序 按人气排序if sort == 'price':sort_field = 'price'elif sort == 'hot':sort_field = '-sales'else:sort = 'default'sort_field = 'create_time'# 3 根据类别信息反向查询,获取商品列表skus = category.sku_set.filter(is_launched=True).order_by(sort_field)# 4 数据分页功能# 创建分页器paginator = Paginator(skus, per_goods_num) # 对skus进行分页,每页显示5条数据# 获取用户当前要看的那一页数据try:page_skus = paginator.page(page_num)except EmptyPage:return HttpResponseForbidden('Empty Page')# 获取总的页码数,前端分页插件中需要使用total_page = paginator.num_pages# 查询商品分类categories = get_categories()# 5 查询面包屑导航:一级 ==>二级==>一级breadcrumb = get_breadcrumb(category)# 6 根据商品类别id,查询所有的在售商品skus = SKU.objects.filter(category_id=category_id, is_launched=True)# 把所有商品的sku id 存放在sku_li中sku_li = [] # 保存当前页所有的sku_idfor sku in skus:sku_li.append(sku.id)# 7 获取每个sku-id的评论数量product_review_num = []for sid in sku_li:# 根据商品id获取已评论的订单order_goods_list = OrderGoods.objects.filter(sku_id=sid, is_commented=True)# 保存每件商品的评价内容product_review_content = []for order_goods in order_goods_list:product_review_content.append(order_goods.comment)product_review_num.append(len(product_review_content))# 获取每页各个商品的评价数量,并保存到列表中per_review_num = [product_review_num[i:i + per_goods_num] for i inrange(0, len(product_review_num), per_goods_num)]# 获取当前访问各个商品的数量cur_per_review_num = per_review_num[page_skus.number - 1]# 8 将每个商品数量赋值给每个商品sku对象# 通过zip函数将sku对象和评价数量进行组合,格式为:[(sku对象,商品评价数量)]for sku in list(zip(page_skus, cur_per_review_num)):# 动态添加商品评价数量review_num属性sku[0].review_num = sku[1]context = {'category_id': category_id,'sort': sort,'page_skus': page_skus,'page_num': page_num,'total_page': total_page,'categories': categories,'breadcrumb': breadcrumb,}print(context)return render(request, 'list.html', context)
在goods应用下定义constants.py,其中定义常量
# 每页显示商品数量
PER_PRODUCTS_LIMIT = 5
上面代码中用的get_breadcrumb(category)
函数定义在goods/utils.py中,参数为类别对象。
def get_breadcrumb(category):"""获取面包屑导航:param category:类别对象:一级 二级 三级:return:一级:返回一级 二级:返回一级+二级 三级:一级+二级+三级"""breadcrumb = {'cat1': '','cat2': '','cat3': '',}if category.parent == None: # 一级类别breadcrumb['cat1'] = categoryelif category.subs.count() == 0: # 三级类别cat2 = category.parentbreadcrumb['cat1'] = cat2.parentbreadcrumb['cat2'] = cat2breadcrumb['cat3'] = categoryelse: # 二级类别breadcrumb['cat1'] = category.parentbreadcrumb['cat2'] = categoryreturn breadcrumb
第2步:定义热销排行视图类,用于展示与商品列表同类别的、销量前2名的商品,
#goods应用下views.py
class HostGoodsView(View):"""热销排行"""def get(self, request, category_id):# 1 查询热销数据(结果为SKU模型类的对象列表)skus = SKU.objects.filter(category_id=category_id, is_launched=True).order_by('-sales')[:2]# 2 将模型列表转字典构造JSON数据hot_skus = []for sku in skus:sku_dict = {'id': sku.id,'name': sku.name,'price': sku.price,# 'default_image_url': settings.STATIC_URL + 'images/goods/' + sku.default_image.url + '.jpg''default_image_url': "http://localhost:8000/" + settings.STATIC_URL + 'images/goods/' + sku.default_image.url + '.jpg'}hot_skus.append(sku_dict)return JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'hot_skus': hot_skus})
第3步:定义展示商品详情的视图类,获取用户点击的商品。
#goods应用下views.py
class DetailView(View):"""商品详情页"""def get(self, request, sku_id):"""提供商品详情页"""# 获取当前sku的信息try:sku = SKU.objects.get(id=sku_id)except SKU.DoesNotExist:return render(request, '404.html')# 查询商品频道分类categories = get_categories()# 查询面包屑导航breadcrumb = get_breadcrumb(sku.category)# 构建当前商品的规格键sku_specs = sku.specs.order_by('spec_id')sku_key = []for spec in sku_specs:sku_key.append(spec.option.id)# 获取当前商品的所有SKUskus = sku.spu.sku_set.all()# 构建不同规格参数(选项)的sku字典spec_sku_map = {}for s in skus:# 获取sku的规格参数s_specs = s.specs.order_by('spec_id')# 用于形成规格参数-sku字典的键key = []for spec in s_specs:key.append(spec.option.id)# 向规格参数-sku字典添加记录spec_sku_map[tuple(key)] = s.id# 获取当前商品的规格信息goods_specs = sku.spu.specs.order_by('id')# 若当前sku的规格信息不完整,则不再继续if len(sku_key) < len(goods_specs):returnfor index, spec in enumerate(goods_specs):key = sku_key[:]# 该spu商品的所有规格选项spec_options = spec.options.all()for option in spec_options:# 在规格参数sku字典中查找符合当前规格的skukey[index] = option.id # 设置当前商品的规格参数option.sku_id = spec_sku_map.get(tuple(key))spec.spec_options = spec_options# 渲染页面context = {'categories': categories,'breadcrumb': breadcrumb,'sku': sku,'stock': sku.stock,'specs': goods_specs,}return render(request, 'detail.html', context)
第4步:定义订单评价视图类,查询某个商品的评价信息,由于尚未完成订单的支付功能,系统中没有订单信息,所以这里是查询不到评价的。
class GoodsCommentView(View):"""订单商品评价信息"""def get(self, request, sku_id):# 获取被评价的订单商品信息order_goods_list = OrderGoods.objects.filter(sku_id=sku_id, is_commented=True).order_by('-create_time')[:30]comment_list = []for order_goods in order_goods_list:username = order_goods.order.user.usernamecomment_list.append({'username': username[0] + '***' + username[-1]if order_goods.is_anonymous else username,'comment': order_goods.comment,'score': order_goods.score,})return JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK','comment_list': comment_list})
第5步:订单商品模型,定义在orders应用models.py中
from django.db import models# Create your models here.
from xiaoyu_mall_new.utils.models import BaseModel
from users.models import User, Address
from goods.models import SKUclass OrderInfo(BaseModel):"""订单信息"""PAY_METHODS_ENUM = {"CASH": 1,"ALIPAY": 2}PAY_METHOD_CHOICES = ((1, "货到付款"),(2, "支付宝"),)ORDER_STATUS_ENUM = {"UNPAID": 1,"UNSEND": 2,"UNRECEIVED": 3,"UNCOMMENT": 4,"FINISHED": 5}ORDER_STATUS_CHOICES = ((1, "待支付"),(2, "待发货"),(3, "待收货"),(4, "待评价"),(5, "已完成"),(6, "已取消"),)order_id = models.CharField(max_length=64, primary_key=True, verbose_name="订单号")user = models.ForeignKey(User, on_delete=models.PROTECT, verbose_name="下单用户")address = models.ForeignKey(Address, on_delete=models.PROTECT, verbose_name="收货地址")total_count = models.IntegerField(default=1, verbose_name="商品总数")total_amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="商品总金额")freight = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="运费")pay_method = models.SmallIntegerField(choices=PAY_METHOD_CHOICES, default=1, verbose_name="支付方式")status = models.SmallIntegerField(choices=ORDER_STATUS_CHOICES, default=1, verbose_name="订单状态")class Meta:db_table = "tb_order_info"verbose_name = '订单基本信息'verbose_name_plural = verbose_namedef __str__(self):return self.order_idclass OrderGoods(BaseModel):"""订单商品"""SCORE_CHOICES = ((0, '0分'),(1, '20分'),(2, '40分'),(3, '60分'),(4, '80分'),(5, '100分'),)order = models.ForeignKey(OrderInfo, related_name='skus',on_delete=models.CASCADE, verbose_name="订单")sku = models.ForeignKey(SKU, on_delete=models.PROTECT,verbose_name="订单商品")count = models.IntegerField(default=1, verbose_name="数量")price = models.DecimalField(max_digits=10, decimal_places=2,verbose_name="单价")comment = models.TextField(default="", verbose_name="评价信息")score = models.SmallIntegerField(choices=SCORE_CHOICES, default=5,verbose_name='满意度评分')is_anonymous = models.BooleanField(default=False,verbose_name='是否匿名评价')is_commented = models.BooleanField(default=False,verbose_name='是否评价了')class Meta:db_table = "tb_order_goods"verbose_name = '订单商品'verbose_name_plural = verbose_namedef __str__(self):return self.sku.name
对上面的模型生成迁移文件,并执行迁移文件。
第5步:定义路由,goods应用下urls.py配置路由。
from django.urls import pathfrom goods import viewsapp_name = 'goods'
urlpatterns = [path('list/<int:category_id>/<int:page_num>/', views.ListView.as_view(), name='list'),path('hot/<int:category_id>/', views.HostGoodsView.as_view()),path('detail/<int:sku_id>/', views.DetailView.as_view(), name='detail'),
]
根路由中增加
path('', include('goods.urls')),
第6步:查询到的商品列表展示在list.html模板中
{#<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">#}
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"><title>小鱼商城-商品列表</title><link rel="stylesheet" type="text/css" href="{{ static('css/jquery.pagination.css') }}"><link rel="stylesheet" type="text/css" href="{{ static('css/reset.css') }}"><link rel="stylesheet" type="text/css" href="{{ static('css/main.css') }}"><script type="text/javascript" src="{{ static('js/jquery-1.12.4.min.js') }}"></script><script type="text/javascript" src="{{ static('js/vue-2.5.16.js') }}"></script><script type="text/javascript" src="{{ static('js/axios-0.18.0.min.js') }}"></script>
</head>
<body>
<div id="app"><div class="header_con"><div class="header" v-cloak><div class="welcome fl">欢迎来到小鱼商城!</div><div class="fr"><div v-if="username" class="login_btn fl">欢迎您:<em>[[ username ]]</em><span>|</span><a href="{{ url('users:logout') }}">退出</a></div><div v-else class="login_btn fl"><a href="{{ url('users:login') }}">登录</a><span>|</span><a href="{{ url('users:register') }}">注册</a></div><div class="user_link fl"><span>|</span><a href="{{ url('users:info') }}">用户中心</a><span>|</span>{# <a href="{{ url('carts:info') }}">我的购物车</a>#}<span>|</span>{# <a href="{{ url('users:myorderinfo',args=(1,)) }}">我的订单</a>#}</div></div></div></div><div class="search_bar clearfix"><a href="{{ url('contents:index') }}" class="logo fl"><img src="{{ static('images/logo.png') }}"></a><div class="search_wrap fl"><form method="get" action="/search/" class="search_con"><input type="text" class="input_text fl" name="q" placeholder="搜索商品"><input type="submit" class="input_btn fr" name="" value="搜索"></form><ul class="search_suggest fl"><li><a href="#">索尼微单</a></li><li><a href="#">优惠15元</a></li><li><a href="#">美妆个护</a></li><li><a href="#">买2免1</a></li></ul></div><div @mouseenter="get_carts" class="guest_cart fr" v-cloak>{# <a href="{{ url('carts:info') }}" class="cart_name fl">我的购物车</a>#}<div class="goods_count fl" id="show_count">[[ cart_total_count ]]</div><ul class="cart_goods_show"><li v-for="sku in carts"><img :src="sku.default_image_url" alt="商品图片"><h4>[[ sku.name ]]</h4><div>[[ sku.count ]]</div></li></ul></div></div><div class="navbar_con"><div class="navbar"><div class="sub_menu_con fl"><h1 class="fl">商品分类</h1><ul class="sub_menu">{% for group in categories.values() %}<li><div class="level1">{% for channel in group.channels %}<a href="{{ channel.url }}">{{ channel.name }}</a>{% endfor %}</div><div class="level2">{% for cat2 in group.sub_cats %}<div class="list_group"><div class="group_name fl">{{ cat2.name }} ></div><div class="group_detail fl">{% for cat3 in cat2.sub_cats %}<a href="/list/{{ cat3.id }}/1/">{{ cat3.name }}</a>{% endfor %}</div></div>{% endfor %}</div></li>{% endfor %}</ul></div><ul class="navlist fl"><li><a href="">首页</a></li><li class="interval">|</li><li><a href="">真划算</a></li><li class="interval">|</li><li><a href="">抽奖</a></li></ul></div></div><div class="breadcrumb"><a href="javascript:;">{{ breadcrumb.cat1.name }}</a><span>></span><a href="javascript:;">{{ breadcrumb.cat2.name }}</a><span>></span><a href="javascript:;">{{ breadcrumb.cat3.name }}</a></div><div class="main_wrap clearfix"><div class="l_wrap fl clearfix"><div class="new_goods"><h3>热销排行</h3><ul><li v-for="sku in hot_skus">
{# <a :href="sku.url"><img :src="sku.default_image_url"></a>#}<a :href="sku.url"><img :src="sku.default_image_url"></a><h4><a :href="sku.url">[[ sku.name ]]</a></h4><div class="price">¥[[ sku.price ]]</div></li></ul></div></div><div class="r_wrap fr clearfix"><div class="sort_bar"><a href="{{ url('goods:list',args=(category_id,1)) }}?sort=default"{% if sort=='default' %}class="active" {% endif %}>默认</a><a href="{{ url('goods:list',args=(category_id,1)) }}?sort=price"{% if sort=='price' %}class="active" {% endif %}>价格</a><a href="{{ url('goods:list',args=(category_id,1)) }}?sort=hot" {% if sort=='hot' %} class="active" {%endif %}>人气</a></div><ul class="goods_type_list clearfix">{% for sku in page_skus %}<li><a href="{{ url('goods:detail',args=(sku.id,)) }}"><img src="/static/images/goods/{{ sku.default_image }}.jpg"></a><h4><a href="{{ url('goods:detail',args=(sku.id,)) }}">{{ sku.name }}</a></h4><div class="operate"><span class="price">¥{{ sku.price }}</span><span class="unit">{{ sku.review_num }}条评价</span><a href="#" class="add_goods" title="加入购物车"></a></div></li>{% endfor %}</ul>{# 前端分页器插件内容 #}<div class="pagenation"><div id="pagination" class="page"></div></div></div></div><div class="footer"><div class="foot_link"><a href="#">关于我们</a><span>|</span><a href="#">联系我们</a><span>|</span><a href="#">招聘人才</a><span>|</span><a href="#">友情链接</a></div><p>CopyRight © 2024 北京小鱼商业股份有限公司 All Rights Reserved</p><p>电话:010-****888 京ICP备*******8号</p></div>
</div>
<script type="text/javascript">let category_id = "{{ category_id }}";
</script>
<script type="text/javascript" src="{{ static('js/common.js') }}"></script>
<script type="text/javascript" src="{{ static('js/list.js') }}"></script>
<script type="text/javascript" src="{{ static('js/jquery.pagination.min.js') }}"></script>
<script>$(function () {$('#pagination').pagination({currentPage: {{ page_num }},totalPage: {{ total_page }},callback: function (current) {location.href = '/list/{{ category_id }}/' + current + '/?sort={{ sort }}';}})});
</script>
</body>
</html>
第7步:商品详情页面
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"><title>小鱼商城-商品详情</title><link rel="stylesheet" type="text/css" href="{{ static('css/reset.css') }}"><link rel="stylesheet" type="text/css" href="{{ static('css/main.css') }}"><script type="text/javascript" src="{{ static('js/vue-2.5.16.js') }}"></script><script type="text/javascript" src="{{ static('js/axios-0.18.0.min.js') }}"></script>
</head>
<body>
<div id="app"><div class="header_con"><div class="header" v-cloak><div class="welcome fl">欢迎来到小鱼商城!</div><div class="fr"><div v-if="username" class="login_btn fl">欢迎您:<em>[[ username ]]</em><span>|</span><a href="{{ url('users:logout') }}">退出</a></div><div v-else class="login_btn fl"><a href="{{ url('users:login') }}">登录</a><span>|</span><a href="{{ url('users:register') }}">注册</a></div><div class="user_link fl"><span>|</span><a href="{{ url('users:info') }}">用户中心</a><span>|</span>{# <a href="{{ url('carts:info') }}">我的购物车</a>#}<span>|</span>{# <a href="{{ url('users:myorderinfo',args=(1,)) }}">我的订单</a>#}</div></div></div></div><div class="search_bar clearfix"><a href="{{ url('contents:index') }}" class="logo fl"><img src="{{ static('images/logo.png') }}"></a><div class="search_wrap fl"><form method="get" action="/search/" class="search_con"><input type="text" class="input_text fl" name="q" placeholder="搜索商品"><input type="submit" class="input_btn fr" name="" value="搜索"></form><ul class="search_suggest fl"><li><a href="#">索尼微单</a></li><li><a href="#">优惠15元</a></li><li><a href="#">美妆个护</a></li><li><a href="#">买2免1</a></li></ul></div><div @mouseenter="get_carts" class="guest_cart fr" v-cloak>{# <a href="{{ url('carts:info') }}" class="cart_name fl">我的购物车</a>#}<div class="goods_count fl" id="show_count">[[ cart_total_count ]]</div><ul class="cart_goods_show"><li v-for="sku in carts"><img :src="sku.default_image_url" alt="商品图片"><h4>[[ sku.name ]]</h4><div>[[ sku.count ]]</div></li></ul></div></div><div class="navbar_con"><div class="navbar"><div class="sub_menu_con fl"><h1 class="fl">商品分类</h1><ul class="sub_menu">{% for group in categories.values() %}<li><div class="level1">{% for channel in group.channels %}<a href="{{ channel.url }}">{{ channel.name }}</a>{% endfor %}</div><div class="level2">{% for cat2 in group.sub_cats %}<div class="list_group"><div class="group_name fl">{{ cat2.name }} ></div><div class="group_detail fl">{% for cat3 in cat2.sub_cats %}<a href="/list/{{ cat3.id }}/1/">{{ cat3.name }}</a>{% endfor %}</div></div>{% endfor %}</div></li>{% endfor %}</ul></div><ul class="navlist fl"><li><a href="">首页</a></li><li class="interval">|</li><li><a href="">真划算</a></li><li class="interval">|</li><li><a href="">抽奖</a></li></ul></div></div><div class="breadcrumb"><a href="javascript:;">{{ breadcrumb.cat1.name }}</a><span>></span><a href="javascript:;">{{ breadcrumb.cat2.name }}</a><span>></span><a href="javascript:;">{{ breadcrumb.cat3.name }}</a></div><div class="goods_detail_con clearfix"><div class="goods_detail_pic fl"><img src="/static/images/goods/{{ sku.default_image }}.jpg"></div><div class="goods_detail_list fr"><h3>{{ sku.name }}</h3><p>{{ sku.caption }}</p><div class="price_bar"><span class="show_pirce">¥<em>{{ sku.price }}</em></span><a href="javascript:;" class="goods_judge" v-cloak>[[ comments.length ]]人评价</a></div><div class="goods_num clearfix"><div class="num_name fl">数 量:</div><div class="num_add fl"><input v-model="sku_count" @blur="check_sku_count" type="text" class="num_show fl"><a @click="on_addition" class="add fr">+</a><a @click="on_minus" class="minus fr">-</a></div></div>{% for spec in specs %}<div class="type_select"><label>{{ spec.name }}:</label>{% for option in spec.spec_options %}{% if option.sku_id == sku.id %}<a href="javascript:;" class="select">{{ option.value }}</a>{% elif option.sku_id %}<a href="{{ url('goods:detail', args=(option.sku_id, )) }}">{{ option.value }}</a>{% else %}<a href="javascript:;">{{ option.value }}</a>{% endif %}{% endfor %}</div>{% endfor %}<div class="total" v-cloak>总价:<em>[[ sku_amount ]]元</em></div><div class="operate_btn"><a @click="add_carts" 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><li v-for="sku in hot_skus"><a :href="sku.url"><img :src="sku.default_image_url"></a><h4><a :href="sku.url">[[ sku.name ]]</a></h4><div class="price">¥[[ sku.price ]]</div></li></ul></div></div><div class="r_wrap fr clearfix"><ul class="detail_tab clearfix"><li @click="on_tab_content('detail')" :class="tab_content.detail?'active':''">商品详情</li><li @click="on_tab_content('pack')" :class="tab_content.pack?'active':''">规格与包装</li><li @click="on_tab_content('service')" :class="tab_content.service?'active':''">售后服务</li><li @click="on_tab_content('comment')" :class="tab_content.comment?'active':''">商品评价([[comments.length ]])</li></ul><div @click="on_tab_content('detail')" class="tab_content" :class="tab_content.detail?'current':''"><dl><dt>商品详情:</dt><dd>{{ sku.spu.desc_detail|safe }}</dd></dl></div><div @click="on_tab_content('pack')" class="tab_content" :class="tab_content.pack?'current':''"><dl><dt>规格与包装:</dt><dd>{{ sku.spu.desc_pack|safe }}</dd></dl></div><div @click="on_tab_content('service')" class="tab_content" :class="tab_content.service?'current':''"><dl><dt>售后服务:</dt><dd>{{ sku.spu.desc_service|safe }}</dd></dl></div>{# 商品评价内容#}<div @click="on_tab_content('comment')" class="tab_content" :class="tab_content.comment?'current':''"><ul class="judge_list_con"><li class="judge_list fl" v-for="comment in comments"><div class="user_info fl"><b>[[comment.username]]</b></div><div class="judge_info fl"><div :class="comment.score_class"></div><div class="judge_detail">[[comment.comment]]</div></div></li></ul></div></div></div><div class="footer"><div class="foot_link"><a href="#">关于我们</a><span>|</span><a href="#">联系我们</a><span>|</span><a href="#">招聘人才</a><span>|</span><a href="#">友情链接</a></div><p>CopyRight © 2024 北京小鱼商业股份有限公司 All Rights Reserved</p><p>电话:010-****888 京ICP备*******8号</p></div>
</div>
<script type="text/javascript">let category_id = "{{ sku.category.id }}";let sku_price = "{{ sku.price }}";let sku_id = "{{ sku.id }}";let stock = "{{ stock }}"
</script>
<script type="text/javascript" src="{{ static('js/common.js') }}"></script>
<script type="text/javascript" src="{{ static('js/detail.js') }}"></script>
</body>
</html>