介绍
这部分主要是,添加一个商品类和分类类,在首页根据分类来列出一些商品,而列出的顺序可以是,时间顺序,点击量,或是价格排序
1. 创建模型类
添加商品类和分类类,两表之间是一对多的关系
class TypeInfo(models.Model):
ttitle = models.CharField(max_length=20)
isDelete = models.BooleanField(default=False) #使用逻辑删除
def __str__(self): #这里是 在admin显示的内容
return self.ttitle
class GoodInfo(models.Model):
gtitle = models.CharField(max_length=50)
gpic = models.ImageField(upload_to='df_goods') #这个其实存的是路劲,admin中添加时同时上传了文件,需要pillow
gprice = models.DecimalField(max_digits=5, decimal_places=2)
isDelete = models.BooleanField(default=False)
gunit = models.CharField(max_length=20,default='500g')
gclick = models.IntegerField()#点击量
gintro = models.CharField(max_length=100)#简介
gdetial = HTMLField()
gtype = models.ForeignKey("TypeInfo") #外键
gkucun = models.IntegerField(default=0) # 库存
# gadv = models.BooleanField(default=False)#推荐 广告商品
def __str__(self):
return self.gtitle
不要忘了生成迁移,然后在admin.py里注册,,这两个模型类,可以在admin里造一点数据。
2. 建立视图函数
首页视图
这里首先获得所有的分类,然后遍历这个分类列表,将其中的查询到的商品分别按id和点击量倒叙排的前四个,并将他们按键值的方式,储存到context字典中。模板中就可以根据分类来获得不同的商品列表并显示出来
def index(request):
context = {'guest_cart': 1,
'title': '首页'}
#获得最新火的4 个 商品
hot = GoodInfo.objects.all().order_by('-gclick')[0:4]
context.setdefault('hot',hot)
#****获得各分类下的点击商品************
# 先获得所有分类
typelist = TypeInfo.objects.all()
for i in range(len(typelist)):
# 获得type对象
type = typelist[i]
# 根据type对象获取商品列表
# 通过外键关联获取商品
# 获取 对应 列表中的通过 id 倒序排列的 前四个
goods1 = type.goodinfo_set.order_by('-id')[0:4]
goods2 = type.goodinfo_set.order_by('-gclick')[0:4]
key1 = 'type' + str(i) # 根据id 倒叙排列
key2 = 'type' + str(i) + str(i) # 根据点击量倒序排列
context.setdefault(key1, goods1)
context.setdefault(key2, goods2)
print(context)
return render(request, 'df_goods/index.html', context)
商品分类列表
点击首页的分类导航,进入商品的分类列表,该列表主要显示这类商品下的所有商品,并提供按时间,点击量,价格排序的功能,还有分页
#商品列别界面,要接受多个参数
#1,type id
#2. 排序 的方式
#3. 分页的页码
def list(request,tid,sid,pindex):
from django.core.paginator import Paginator,Page
type = TypeInfo.objects.get(pk=int(tid))
news = type.goodinfo_set.order_by('-id')[0:2]
if sid == '1':
good_list = type.goodinfo_set.order_by('-id')#按时间最新的排列
if sid == '2':
good_list = GoodInfo.objects.filter(gtype_id=int(tid)).order_by('-gprice')#按价格
if sid == '3':
good_list = GoodInfo.objects.filter(gtype_id=int(tid)).order_by('-gclick')
#创建paginator分页对象
paginator = Paginator(good_list,10)
#返回Page对象,包含商品信息
page = paginator.page(int(pindex))
context = {'title':'商品列表',
'guest_cart':1,
'page':page,
'paginator':paginator,
'typeinfo':type,
'sort':sid,#排序方式
'news':news,
}
return render(request,'df_goods/list.html',context)
这里要根据视图函数的参数来设计url,一个参数 分类id,排序方式,和页码,所以这样写url
url(r'^list_(\d+)_(\d+)_(\d+)$',views.list),
模板中的分页是这样完成的
<div class="pagenation">
{# 判断是否是第一页#}
{% if page.has_previous %}
<a href="/list_{{ typeinfo.id }}_{{ sort }}_{{ page.previous_page_number }}">上一页</a>
{% endif %}
{# paginator.page_range为页码总数#}
{% for pindex in paginator.page_range %}
{# 是否为当前页#}
{% if page.number == pindex %}
<a href="/list_{{ typeinfo.id }}_{{ sort }}_{{pindex}}" class="active">{{ pindex }}</a>
{% else %}
<a href="/list_{{ typeinfo.id }}_{{ sort }}_{{pindex}}">{{ pindex }}</a>
{% endif %}
{% endfor %}
{% if page.has_next %}
<a href="/list_{{ typeinfo.id }}_{{ sort }}_{{ page.next_page_number }}">下一页></a>
{% endif %}
</div>
商品详情页面
商品详情页面的url是这样设定的
url(r'^(\d+)$',views.detail),
详情页就是将查询到的商品信息,添加到模板页面里,详情页里的商品数量的加减以及小计和加入购物车可以用js完成
def detail(request,id):
goods = GoodInfo.objects.filter(pk=int(id)).first()
goods.gclick += 1 #点击量加1
goods.save()
from df_cart.models import Cart
#返回用于显示购物车内商品总数
cart_count = Cart.objects.filter(user_id=request.session.get('uid',0)).count()
news = goods.gtype.goodinfo_set.order_by('-id')[0:2]
context = {'title':goods.gtype.ttitle,
'goods':goods,
'cart_count':cart_count,
'news':news,
'guest_cart':1,
'typeinfo':goods.gtype
}
response = render(request,'df_goods/detail.html',context)
#接下来,要将浏览信息,存入 cookie ,以便 最近浏览 功能使用
#存入 cookie 的形式微 { 'gooids':'1,5,6,7,8,9'}
#id间已逗号隔开
goodids = request.COOKIES.get('goodids','')
if goodids != '':
goodidsl = goodids.split(',') #将字符串 拆分成 列表
if goodidsl.count(id) >=1 :#先判断 是否已经存在列表里
#如果已经存在,则删除存在的元素,之后会插入新的
goodidsl.remove(id)
#将新的id放在 列表的 第一个
goodidsl.insert(0,id)
if len(goodidsl) >=6:#如果超过 6个,则删除最后一个,相当于长度为5的队列
del goodidsl[5]
goodids = ','.join(goodidsl)#将列表,以逗号分割的形式 拼接为字符串
else:#如果为空则 直接 添加
goodids = id
response.set_cookie('goodids',goodids)
return response
这里还有一个重要问题是浏览历史问题,当进入到详情页后,将这件商品的id存入cookie里,然后在需要的地方解析出商品即可
这是计算小计和数量加减的js
<script>
function plus() {
num = parseFloat($('.num_show').val());
$('.num_show').val(num+1);
$('.num_show').blur();
}
function minus() {
num = parseFloat($('.num_show').val());
$('.num_show').val(num-1);
$('.num_show').blur();
}
$(function () {
$('.num_show').blur(function () {
num = parseFloat($('.num_show').val());
price = parseFloat($('#gprice').text());
total = num*price;
$('#gtotal').text(total.toFixed(2)+'元')
})
})
在此商品展示的部分就完了,下一部分是购物车。