项目环境
- django版本: 1.11.11
- python版本:3.6
- 编辑器:pycharm 2019.1.1 专业版
商品信息分页及搜索
实现步骤
- mysql数据库中建立goods数据表,所需字段及类型都需在数据库设计阶段完成,sql语句如下所示:
DROP TABLE IF EXISTS `goods`;
CREATE TABLE `goods` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`typeid` int(11) unsigned NOT NULL,
`goods` varchar(32) NOT NULL,
`company` varchar(50) DEFAULT NULL,
`content` text,
`price` double(6,2) unsigned NOT NULL,
`picname` varchar(255) DEFAULT NULL,
`store` int(11) unsigned NOT NULL DEFAULT '0',
`num` int(11) unsigned NOT NULL DEFAULT '0',
`clicknum` int(11) unsigned NOT NULL DEFAULT '0',
`state` tinyint(1) unsigned NOT NULL DEFAULT '1',
`addtime` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `typeid` (`typeid`)
) ENGINE=MyISAM AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
- 在models.py中定义模型类,模型类可用于生成数据库表,模型类的存在是使更换数据库更加方便。常用的字段类型有:IntegerFild(),CharFiled(),DateTimeFiled()。toDict()函数返回一个字典供前台使用。_str_()方法是在使用django自带shell查询数据库时返回对象的内容时使用。
# 商品信息模型
class Goods(models.Model):
typeid = models.IntegerField()
goods = models.CharField(max_length=32)
company = models.CharField(max_length=50)
content = models.TextField()
price = models.FloatField()
picname = models.CharField(max_length=255)
store = models.IntegerField(default=0)
num = models.IntegerField(default=0)
clicknum = models.IntegerField(default=0)
state = models.IntegerField(default=1)
addtime = models.DateTimeField(default=datetime.now)
def toDict(self):
return {'id': self.id, 'typeid': self.typeid, 'goods': self.goods, 'company': self.company, 'price': self.price,
'picname': self.picname, 'store': self.store, 'num': self.num, 'clicknum': self.clicknum,
'state': self.state}
def __str__(self):
return "%d--%d--%s--%s--%f--%s--%s--%d--%d--%d" % (self.id, self.typeid, self.goods, self.company, self.price, self.picname, self.store, self.num, self.clicknum, self.state)
class Meta:
db_table = "goods" # 更改表名
- 在/myadmin/urls.py中实现路由配置,django1.11的与django2.0的路由配置不同,尤其需要注意。
# 后台商品类别信息管理
url(r'^type$', type.index, name="myadmin_type_index"),
url(r'^type/add/(?P<tid>[0-9]+)$', type.add, name="myadmin_type_add"),
url(r'^type/insert$', type.insert, name="myadmin_type_insert"),
url(r'^type/del/(?P<tid>[0-9]+)$', type.delete, name="myadmin_type_del"),
url(r'^type/edit/(?P<tid>[0-9]+)$', type.edit, name="myadmin_type_edit"),
url(r'^type/update/(?P<tid>[0-9]+)$', type.update, name="myadmin_type_update"),
- 编辑视图文件
视图文件是实现分页功能的重点,index方法实现了商品信息的分页浏览。
要导入的包:
from common.models import Types, Goods
from django.db.models import Q # 用于查询满足不同字段的条件查询
from django.core.paginator import Paginator # 用于分页
实现代码如下:
# 浏览商品信息
def index(request, pIndex):
'''浏览信息'''
# 获取商品类别信息
tlist = Types.objects.extra(select={'_has': 'concat(path,id)'}).order_by('_has')
for ob in tlist:
ob.pname = '. . .' * (ob.path.count(',') - 1)
获取商品类别信息并按分类等级排序,for循环控制显示,美化界面。
# 搜索功能
# 获取商品信息查询对象
mod = Goods.objects
mywhere = [] # 定义一个用于存放搜索条件列表
# 获取、判断并封装关keyword键搜索
kw = request.GET.get("keyword", None)
if kw:
# 查询商品名中只要含有关键字的都可以,忽略大小写
list = mod.filter(goods__icontains=kw)
mywhere.append("keyword=" + kw)
else:
list = mod.filter()
# 获取、判断并封装商品类别typeid搜索条件
typeid = request.GET.get('typeid', '0')
if typeid != '0':
# 查询id或者pid等于输入的typeid的记录
tids = Types.objects.filter(Q(id=typeid) | Q(pid=typeid)).values_list('id', flat=True)
# 结合list变量结果链接查询
list = list.filter(typeid__in=tids)
mywhere.append("typeid=" + typeid)
# 获取、判断并封装商品状态state搜索条件
state = request.GET.get('state', '')
if state != '':
list = list.filter(state=state)
mywhere.append("state=" + state)
# 执行分页处理
pIndex = int(pIndex)
page = Paginator(list, 5) # 以5条每页创建分页对象,这里的list是经过筛选过后的结果
maxpages = page.num_pages # 最大页数
# 判断页数是否越界
if pIndex > maxpages:
pIndex = maxpages
if pIndex < 1:
pIndex = 1
list2 = page.page(pIndex) # 当前页数据
plist = page.page_range # 页码数列表
# 遍历商品信息,并获取对应的商品类别名称,以typename名封装
for vo in list2:
ty = Types.objects.get(id=vo.typeid)
vo.typename = ty.name
print(vo.typename)
for vo2 in list2:
print(vo2.id, vo2.goods)
# 封装信息加载模板输出
context = {'typelist': tlist, "goodslist": list2, 'plist': plist, 'pIndex': pIndex, 'maxpages': maxpages,
'mywhere': mywhere, 'typeid': int(typeid)}
return render(request, "myadmin/goods/index.html", context)
- 编辑模板文件
模板文件中写的是html代码,重点是分页搜索的状态维持,此处需通过get方式传递参数。?{{ mywhere|join:’&’ }}用于状态保持,点击搜索按钮后,每页的数据符合条件的都被搜索出来,然后在分页显示搜索结果。搜索在前,分页在后。有了参数才能将搜索出的数据显示出来。
<div class="pagination">
<ul>
<li {% if pIndex == 1 %}class="disabled" {% endif %}>
<a href="{% url 'myadmin_goods_index' pIndex|add:-1 %}?{{ mywhere|join:'&' }}">«</a>
</li>
{% for p in plist %}
<li {% if pIndex == p %}class="active"{% endif %}>
<a href="{% url 'myadmin_goods_index' p %}?{{ mywhere|join:'&' }}">{{p}}</a>
</li>
{% endfor %}
<li {% if pIndex == maxpages %}class="disabled" {% endif %}>
<a href="{% url 'myadmin_goods_index' pIndex|add:1 %}?{{ mywhere|join:'&' }}">»</a>
</li>
</ul>
</div>
总结
在学这些东西的时候,一定要告诉自己,有些想不明白的东西就先不要想,只管使用框架提供的这些好用的方法即可。
很久不做笔记,也不知道笔记的重点在哪里。小时候读书,我就是能看懂别人的笔记,别人看不懂我的笔记的人,一是字太丑,二是笔记记得毫无规律。加油吧,从做笔记开始。