实现商城的列表页与详情页
这几天做项目做到了商城的列表页与详情页,需要将数据库的数据展示到前端来,我这里写了关于前端与后端的代码实现
1、创建商品模块
这里需要先创建一个商品的模块,用来对商品进行一系列的操作
在终端输入python ../../manage.py startapp goods
这里我是将goods模块创建到apps文件夹里,而apps文件夹是在项目所在的同名文件夹里创建的,manage.py文件是在项目所在的文件夹里,所以用../../manage.py
相对路径。
当然你也可以直接cd到项目所在的文件夹里直接进行python manage.py startapp goods
操作,这样goods模块就会创建到项目所在的文件夹里
创建完模块之后就得在settings.py文件里的INSTALLED_APPS里进行注册:'goods.apps.GoodsConfig',
然后就是创建表了,在models.py文件里
from django.db import models
from shanghuishop.utils.basemodel import Basemodel
from ckeditor_uploader.fields import RichTextUploadingField
from ckeditor.fields import RichTextField# Create your models here.
class GoodsSort(Basemodel):'''商品的类别'''name = models.CharField(max_length=20,verbose_name='商品类别的名称')pid = models.ForeignKey('self',null=True,blank=True,on_delete=models.CASCADE,verbose_name='父级id')class Meta:db_table = 'sh_goods_sort'verbose_name = '商品的类别'verbose_name_plural = verbose_namedef __str__(self):return self.name+ 'obj'class GoodsBrand(Basemodel):'''品牌'''name = models.CharField(max_length=30,verbose_name='品牌名称')logo = models.ImageField(verbose_name='商品的图标')class Meta:db_table = 'sh_goods_brand'verbose_name = '商品的品牌表'verbose_name_plural = verbose_namedef __str__(self):return self.name + 'obj'class goods(Basemodel):'''商品的SPU'''name = models.CharField(max_length=50,verbose_name='SPU的名称')brand = models.ForeignKey(GoodsBrand,on_delete=models.PROTECT,verbose_name='品牌')cate1 = models.ForeignKey(GoodsSort,on_delete=models.PROTECT,related_name='cate1_goods',verbose_name='一级目录')cate2 = models.ForeignKey(GoodsSort,on_delete=models.PROTECT,related_name='cate2_goods',verbose_name='二级目录')cate3 = models.ForeignKey(GoodsSort,on_delete=models.PROTECT,related_name='cate3_goods',verbose_name='三级目录')sales = models.IntegerField(default=0,verbose_name='销量')commentnum = models.IntegerField(default=0,verbose_name='评论数')detail_introduce = RichTextUploadingField(default='',verbose_name='详情信息')pack_introduce = RichTextField(default='',verbose_name='规格以及包装')class Meta:db_table = 'sh_goods_spu'verbose_name = '商品'verbose_name_plural = verbose_namedef __str__(self):return self.name + 'obj'class Standard(Basemodel):name = models.CharField(max_length=50,verbose_name='规格的名称,类似颜色')goods_spu = models.ForeignKey(goods,on_delete=models.CASCADE,verbose_name='商品spu')class Meta:db_table = 'sh_standard'verbose_name='商品spu的规格属性'verbose_name_plural=verbose_namedef __str__(self):return self.name + 'obj'class StandardDetail(Basemodel):standardvalue = models.CharField(max_length=50,verbose_name='规格属性具体值,类似机身颜色的红色')standards = models.ForeignKey(Standard,on_delete=models.CASCADE,verbose_name='规格属性外键')class Meta:db_table = 'sh_standard_detail'verbose_name = '商品spu的规格属性的详情'verbose_name_plural = verbose_namedef __str__(self):return self.standardvalue + 'obj'class StockKeepingUnit(Basemodel):"""商品SKU"""status_choices = ((0, '下线'),(1, '上线'),)name = models.CharField(max_length=50,verbose_name="SKU名称")brand = models.ForeignKey(GoodsBrand,on_delete=models.PROTECT,verbose_name="品牌")cate3 = models.ForeignKey(GoodsSort,on_delete=models.PROTECT,related_name="cate3_name",verbose_name="三级目录")sales = models.IntegerField(default=0,verbose_name="销量")# standard = models.ForeignKey()commodity_spu = models.ForeignKey(goods,on_delete=models.PROTECT,related_name="commodity_spu",verbose_name="spu名称")price = models.DecimalField(max_digits=10,decimal_places=3,verbose_name="价格")cost = models.DecimalField(default=0,max_digits=10,decimal_places=3,verbose_name="原始价格")stock = models.IntegerField(default=0, verbose_name='商品库存')status = models.SmallIntegerField(default=1, choices=status_choices, verbose_name='商品状态')default_image_url = models.CharField(max_length=500,default='',null=True,blank=True,verbose_name='这是默认的图片')class Meta:db_table = "sh_sku"verbose_name = "商品SKU"verbose_name_plural = verbose_namedef __str__(self):return self.name + "obj"class SKUStandDetail(Basemodel):'''每个sku具体的属性'''sku = models.ForeignKey(StockKeepingUnit,on_delete=models.CASCADE,verbose_name='这是sku')stard = models.ForeignKey(Standard,on_delete=models.CASCADE,verbose_name='规格属性')value = models.ForeignKey(StandardDetail,on_delete=models.CASCADE,verbose_name='规格属性具体值')class Meta:db_table = "sh_sku_stand_value"verbose_name = "商品SKU_规格属性_具体规格属性"verbose_name_plural = verbose_namedef __str__(self):return self.sku.name+self.stard.name+':'+self.value.standardvalueclass StockKeepingUnitImage(Basemodel):"""每个SKU对应的图片"""sku = models.ForeignKey(StockKeepingUnit,on_delete=models.CASCADE,verbose_name='sku')image = models.ImageField(verbose_name='图片')class Meta:db_table = "sh_sku_image"verbose_name = "商品SKU对应图片"verbose_name_plural = verbose_namedef __str__(self):return '%s %s image'%(self.sku.name,self.id) + "obj"
以上的表都是继承我自己写的Basemodel,当然你也可以自己写一个Basemodel,或者直接继承django的models.Model,下面展示我自己写的Basemodel内容:
from django.db import models
class Basemodel(models.Model):# 逻辑删除is_deleted = models.BooleanField(default=False, verbose_name='逻辑删除')# 创建时间createtime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')# 更新时间updatetime = models.DateTimeField(auto_now_add=True, verbose_name='更新时间')class Meta:#标注当前类是一个基类,不需要创建表abstract = True
创建了这么多表之后呢,我们为了能在admin站点里实现一些操作,需要在admin.py文件里注册:
from django.contrib import admin
from . import models
# Register your models here.
admin.site.register(models.goods)
admin.site.register(models.GoodsSort)
admin.site.register(models.GoodsBrand)
admin.site.register(models.StockKeepingUnit)
admin.site.register(models.StockKeepingUnitImage)
admin.site.register(models.Standard)
admin.site.register(models.StandardDetail)
admin.site.register(models.SKUStandDetail)
然后就得迁移文件了,之下如下两个操作:
python ../../manage.py makemigrations
python ../../manage.py migrate
这样我们就可以在admin站点里查看表,并对表进行增删改查操作了
网页输入127.0.0.1:/8000/admin
需要登录管理员账户,自己创建一个
登录进去之后,对我们的表插入一些数据
2、后端实现获取数据(列表页)
首先,我们要获取列表页数据,就得在views.py里面写方法,同时写一个序列化器,将表的数据序列化
这里我先写一个序列化器,用来展示商品的sku表的一些数据,
在goods模块里新建一个名为serializers.py文件,在里面写:
from rest_framework import serializers
from . import modelsclass SkuSerializer(serializers.ModelSerializer):class Meta:model = models.StockKeepingUnitfields = ['id','name','default_image_url','price','stock','cost','commodity_spu']
序列化器写完之后就得在views.py 文件里实现功能
即:
# 导包
from django.shortcuts import render
from rest_framework.generics import ListAPIView,RetrieveAPIView
from rest_framework.response import Response
from rest_framework.filters import OrderingFilter
from . import serializers
from . import models# Create your views here.class ListsGoods(ListAPIView):serializer_class = serializers.SkuSerializerfilter_backends = [OrderingFilter]ordering_fields = ['price','sales']def get_queryset(self):print(111111111111111111111)cate_id = self.kwargs['cate_id']data_list = models.StockKeepingUnit.objects.filter(cate3=cate_id, status=1)print(data_list)return data_list
然后配置url路径,
url(r'^lists/(?P<cate_id>\d+)/',views.ListsGoods.as_view()),
这里传一下cate_id即可从后端获取数据
3、前端页面实现(列表页)
后端路径走通了之后,前端需要获取后端的数据,取出并返回,这里需要给list页面写一个js,用ajax传数据
$.ajax({url:'http://127.0.0.1:8000/goods/lists/11',success:function (data) {html_str='';console.log(data);for(var i=0;i<data.length;i++){// alert(data[i])str1='<li class="gl-item">\n' +' <em class="icon_special tejia"></em>\n' +'\t<div class="Borders">\n' +'\t <div class="img"><a οnclick="goodsid('+data[i]["id"]+','+data[i]["commodity_spu"]+')" href="Product_Detailed.html"><img src="'+data[i]["default_image_url"]+'" style="width:220px;height:220px"></a></div>\n' +'\t <div class="Price"><b>¥'+data[i]["price"]+'</b><span>[¥49.01/500g]</span></div>\n' +'\t <div class="name"><a href="Product_Detailed.html">'+data[i]["name"]+'</a></div>\n' +'\t <div class="Shop_name"><a href="#">三只松鼠旗舰店</a></div>\n' +'\t <div class="p-operate">\n' +'\t <a href="#" class="p-o-btn Collect"><em></em>收藏</a>\n' +'\t <a href="#" class="p-o-btn shop_cart"><em></em>联系我们</a>\n' +'\t </div>\n' +'\t </div>\n' +'\t</li>';html_str+=str1}$('#listshow').html(html_str)}
});
function goodsid(aa,bb) {localStorage.id=aa;localStorage.spu_id=bb;// alert(localStorage.id)
}
这里我对图片设置了一个点击事件,来获取并保存商品sku的id和spu的id,以便我们实现详情页面,跳转到详情页面之后,用这两个id来获取sku商品更加详细的数据。
4、后端做详情页
这里我们的详情页需要获取三张表的数据,分别是sku表,spu表以及规格表,这里我想着前端需要写三个ajax,我们先从序列化器开始,由于sku的序列化器我们已经写好了,所以只需再写spu的序列化器以及规格的序列化器就行了,如下:
class SpuRetrieveSerializer(serializers.ModelSerializer):class Meta:model = models.goodsfields = ['sales','detail_introduce']class StandardDetailSerializer(serializers.ModelSerializer):class Meta:model = models.StandardDetailfields = ['standardvalue','standards']
然后在views.py里实现功能:
# sku的详情展示
class RetrieveGoods(RetrieveAPIView):serializer_class = serializers.SkuSerializerdef get_queryset(self):print(22222222222222222222)pk = self.kwargs['pk']data_list = models.StockKeepingUnit.objects.filter(id=pk, status=1)print(data_list)return data_list# spu的详情展示
class RetrieveGoodsSpu(RetrieveAPIView):serializer_class = serializers.SpuRetrieveSerializerdef get_queryset(self):pk = self.kwargs['pk']data_list = models.goods.objects.filter(id=pk)print(data_list)return data_list# 规格的详情展示
class RetrieveStandardDetail(ListAPIView):serializer_class = serializers.StandardDetailSerializerdef get_queryset(self):pk = self.kwargs['pk']data_list = models.StandardDetail.objects.filter(standards__exact=pk)print(data_list)return data_list
然后配置三个url地址:
url(r'^retrieve/(?P<pk>\d+)/',views.RetrieveGoods.as_view()),url(r'^retrieve_spu/(?P<pk>\d+)/',views.RetrieveGoodsSpu.as_view()),url(r'^standarddetail/(?P<pk>\d+)/',views.RetrieveStandardDetail.as_view()),
至此,后端即可实现传递商品的详情信息到前端
5、前端的详情展示
后端的工作做完之后,就需要前端展示了
在详情页添加js
$(function () {var goodsid = localStorage.id;var goods_spu_id = localStorage.spu_id;// alert(goodsid);// sku信息的展示$.ajax({url : 'http://127.0.0.1:8000/goods/retrieve/'+goodsid+'/',method:'GET',// headers:{'Authorization':'JWT '+token},success:function (data) {name = data['name'];price = data['price'];stock = data['stock'];cost = data['cost'];$('#goodsname').text(name);$('#cost').text(cost);$('#price').text(price);$('#stock').text(stock);},error:function () {alert('请求失败')}});// spu信息的展示$.ajax({url : 'http://127.0.0.1:8000/goods/retrieve_spu/'+goods_spu_id+'/',method:'GET',// headers:{'Authorization':'JWT '+token},success:function (data) {sales = data['sales'];detail_introduce = data['detail_introduce'];$('#sales').text(sales);$('#detail_introduce').text(detail_introduce);},error:function () {alert('请求失败')}});// 颜色规格的展示$.ajax({url : 'http://127.0.0.1:8000/goods/standarddetail/1/',method:'GET',// headers:{'Authorization':'JWT '+token},success:function (data) {html_str='';console.log(data[0]);for(var i=0;i<data.length;i++){console.log(data[i]);str1='<li οnclick="abb(this)">'+data[i]["standardvalue"]+'</li>';html_str+=str1;console.log(html_str)}$("#color").html(html_str)},error:function () {alert('请求失败')}});// 存储规格的展示$.ajax({url : 'http://127.0.0.1:8000/goods/standarddetail/2/',method:'GET',// headers:{'Authorization':'JWT '+token},success:function (data) {html_str='';console.log(data[0]);for(var i=0;i<data.length;i++){console.log(data[i]);str1='<li οnclick="abb(this)">'+data[i]["standardvalue"]+'</li>';html_str+=str1;console.log(html_str)}$("#storage").html(html_str)},error:function () {alert('请求失败')}});});
function abb(obj) {$(obj).attr({class:"guige-cur"});$(obj).siblings().attr({class:""})
}
这样,前端详情页的展示就做好了。
6、结果展示
以上是列表页的展示,由于数据库只写了两条数据,所以就只展示了两个商品的信息,点击一个商品的图片,即可跳转到该商品的的详情页面,如下:
这里的详情页做的比较简陋,而且图片没有更换,但是大致的详情已经展示到了页面上了,至此,两个页面的一些功能已经做好了。当然,你也可以想想用上面的办法,将图片也展示出来,我这里就不写了。
实现商城的列表页与详情页相关推荐
- 织梦 详情页 php,织梦DEDECMS列表页与详情页调用图集多张图片的方法
DEDECMS列表页与详情页调用图集多张图片的方法,先找到include/common.inc.php文件,把下面代码贴进去: function Getimg($aid,$imgwith,$imghe ...
- 列表页详情页html源码,UI布局欣赏:文章列表与内容详情页设计
UI布局欣赏:文章列表与内容详情页设计 3月 23, 2017 评论 Sponsor 信息内容几乎是每个新闻.博客.摄影.社区等类型媒体常用的功能,所以他们一般都会拥有信息的列表页和内容详情页面的设计 ...
- Scrapy翻页爬取示例——列表页、详情页
Scrapy翻页爬取示例--列表页.详情页 引言: 本人最近在帮助同事们爬取一批英-泰双语数据,顺带复习了一下scrapy爬虫相关的知识.下面以简单的小项目为例,一起来开始吧! 示例一:爬取列表页 本 ...
- html列表详情页,如何区分一个页面是列表页还是详情页
解析页面是做爬虫的过程中的重要环节,而且如果站点多了,解析也会变得非常复杂,所以智能化解析就可能是一个不错的解决方案.如果我们能够容忍一定的错误率,那么我们可以利用智能化解析算法帮我们提取一些内容,简 ...
- selenium和Python3.6实现招聘狗网站自动识别验证码登录、列表页、详情页爬取
之所以选择selenium实现登录主要是为了处理验证码,招聘狗网站的验证码图片是拼接出来的,所以我的方法是通过webdriver截图来实现,然后通过打码兔平台获取验证码坐标实现自动自动登录.列表页和详 ...
- 小程序列表页进入详情页
小程序列表页进入详情页 从列表页进入详情页,通过使用本地存储来实现,当我点击的时候,拿到这个索引,并且获取整个对象,存入内存中,然后在详情页onload中get拿到这个数据,放到页面进行展示 1.1 ...
- 微服务商城系统实战 后台管理页面、商家管理页面、商品列表跳转详情页
文章目录 一.后台管理 1.根据点击的 div 展示相应页面 2.解决 height: 100% 不起作用问题 3. th:onclick 引用的函数参数是 model值 二.商家管理 1.th:ea ...
- Vue.js框架简单读取数据库信息并渲染完成news新闻文章列表以及detail详情页功能(小试牛刀)
项目结构 news.html(新闻列表文件) <!doctype html> <html lang="en"> <head><meta c ...
- 列表页进入详情页再返回列表页时,显示默认第一页的bug修复
如图所示,当我点击分页第二页的第一项,进入详情页后,在点击返回按钮,按理说应该返回到列表页第二页,但是却变成了默认的首页 究其原因,大概是在返回列表页时,接口传参的当前页码pageNum默认传的是1, ...
最新文章
- framework7使用笔记
- 昨日关注-你说过的每一句话
- 用Windows Live Writer离线更新博思日志
- Comparable接口与Comparator接口
- 安德鲁斯Launcher得到的装在手机的应用程序列表
- [渝粤教育] 西南科技大学 建筑制图 在线考试复习资料
- matlab 卷积 拉普拉斯滤波,卷积滤波和边缘检测
- centos7默认字体_CentOS7终端的分辨率和字体修改
- DC.SetMapMode()的用法记录
- AsyncTask使用须知
- 微软BI 之SSIS 系列 - 通过设置 CheckPoints 检查点来增强 SSIS Package 流程的重用性...
- 「Leetcode」142.环形链表II:环找到了,那入口呢?
- win8:添加WinJS控件
- ActivityMQ 事务
- 如何复制百度文库的内容
- U盘插入苹果电脑后被分区,在Windows系统用不了怎么办。
- 使用Retryer优雅地实现对Callable各种各样的重试调用
- html添加好友,人人网怎么加好友 人人网怎么通过数字ID加好友
- transform模板函数调用tolower函数报错原因、解决办法
- CentOS7安装IT资产管理系统Snipe-IT