django多条件筛选搜索(项目实例)
多条件搜索在很多网站上都有用到,比如京东,淘宝,51cto,等等好多购物教育网站上都有,当然网上也有很多开源的比楼主写的好的多了去了,仅供参考,哈哈
先来一张效果图吧,不然幻想不出来是什么样的,前端样式很low,毕竟主要是说后台的嘛,前端为了简单测试就简单的写出来啦,喜欢好的样式可以自己去调哈
写后台的应该都知道先从数据库方面入手,所以我们先来设计数据库
数据库设计
1、视频video
复制代码
classVideo(models.Model):
status_choice=(
(0,u''下线''),
(1,u''上线''),
)
level_choice=(
(1,u''初级''),
(2,u''中级''),
(3,u''高级''),
)
status=models.IntegerField(verbose_name=''状态'',choices=status_choice,default=1)
level=models.IntegerField(verbose_name=''级别'',choices=level_choice,default=1)
classification=models.ForeignKey(''Classification'',null=True,blank=True)
weight=models.IntegerField(verbose_name=''权重(按从大到小排列)'',default=0)
title=models.CharField(verbose_name=''标题'',max_length=32)
summary=models.CharField(verbose_name=''简介'',max_length=32)
img=models.ImageField(verbose_name=图片'',upload_to=''./static/images/Video/'')
href=models.CharField(verbose_name=''视频地址'',max_length=256)
create_date=models.DateTimeField(auto_now_add=True)
classMeta:
db_table=''Video''
verbose_name_plural=u''视频''
def__str__(self):
returnself.title
复制代码
2、视频方向Direction
复制代码
classDirection(models.Model):
weight=models.IntegerField(verbose_name=''权重(按从大到小排列)'',default=0)
name=models.CharField(verbose_name=''名称'',max_length=32)
classification=models.ManyToManyField(''Classification'')
classMeta:
db_table=''Direction''
verbose_name_plural=u''方向(视频方向)''
def__str__(self):
returnself.name
复制代码
3、视频分类Classification
复制代码
classClassification(models.Model):
weight=models.IntegerField(verbose_name=''权重(按从大到小排列)'',default=0)
name=models.CharFieldwww.wang027.com(verbose_name=''名称'',max_length=32)
classMeta:
db_table=''Classification''
verbose_name_plural=u''分类(视频分类)''
def__str__(self):
returnself.name
复制代码
好了大家一起来分析下数据库设计
视频方向Direction类和视频分类Classification多对多关系,因为一个视频方向可以有多个分类,一个视频分类也可以有多个视频方向视频分类
Classification视频分类和视频Video类是一对多关系,因为一个分类肯定有好多视频
视频Video类中level_choice与视频也是一对多关系,因为这个也就这三个分类,所以我选择把他放在内存里面取,毕竟这玩意常年不会变
url映射
复制代码
fromdjango.conf.urlsimporturl
fromdjango.contribimportadmin
fromapp01importviews
urlpatterns=[
url(r''^admin/'',admin.site.urls),
url(r''^video-(?P\d+)-(?P\d+)-(?P\d+).html'',views.video),
]
复制代码
输入的url为:http://127.0.0.1:8080/video-0-0-0.html
中间第一个0代表视频方向,第二个0代表食品分类,第三个0是视频等级,这个是根据汽车之间那个二手车学的,用着很方便哈哈
0代表全部,然后递增,当选择运维自动化,第一个0就会变成1
下面那些都是一样的道理
前端代码
前端HTML,有用到django的simple_tag,从总体效果图可以看出,前端主要分为两部分,选择部分和视频展示部分
1、选择部分
复制代码
选择:
{%action_allcurrent_url1%}:
{%foritemindirection_list%}
{%actioncurrent_urlitem%}
{%endfor%}
{%action_allcurrent_url2%}:
{%foriteminclass_list%}
{%actioncurrent_urlitem%}
{%endfor%}
{%action_allcurrent_url3%}:
{%foriteminlevel_list%}
{%actioncurrent_urlitem%}
{%endfor%}
复制代码
中间主要是用simple_tag来做的前端代码
复制代码
@register.simple_tag
defaction_all(current_url,index):
"""
获取当前url,video-1-1-2.html
:paramcurrent_url:
:paramitem:
:return:
"""
url_part_list=current_url.split(''-'')
ifindex==3:
ifurl_part_list[index]=="0.html":
temp="全部"
else:
temp="全部"
url_part_list[index]="0.html"
else:
ifurl_part_list[index]=="0":
temp="全部"
else:
temp="全部"
url_part_list[index]="0"
href=''-''.join(url_part_list)
temp=temp%(href,)
returnmark_safe(temp)
@register.simple_tag
defaction(current_url,item,index):
#videos-0-0-1.html
#item:idname
#video-2-0-0.html
url_part_list=current_url.split(''-'')
ifindex==3:
ifstr(item[''id''])==url_part_list[3].split(''.'')[0]:#如果当前标签被选中
temp="%s"
else:
temp="%s"
url_part_list[index]=str(item[''id''])+''.html''#拼接对应位置的部分url
else:
ifstr(item[''id''])==url_part_list[index]:
temp="%s"
else:
temp="%s"
url_part_list[index]=str(item[''id''])
ur_str=''-''.join(url_part_list)#拼接整体url
temp=temp%(ur_str,item[''name''])#生成对应的a标签
returnmark_safe(temp)#返回安全的html
复制代码
2、视频展示区域
复制代码
视频:
{%foriteminvideo_list%}
{{item.title}}
{{item.summary}}
{%endfor%}
复制代码
关键来啦关键来啦,最主要的处理部分在这里,往这看,往这看,往这看,主要的事情说三遍哈
视频后台逻辑处理部分
复制代码
defvideo(request,args,kwargs):
print(kwargs)
#当前请求的路径
request_path=request.path
#从数据库获取视频时的filter条件字典
q={}
#状态为审核通过的
q[''status'']=1
#获取url中的视频分类id
class_id=int(kwargs.get(''classification_id''))
#从数据库中获取所有的视频方向(包括视频方向的id和name)
direction_list=models.Direction.objects.all().values(''id'',''name'')
#如果视频方向是0
ifkwargs.get(''direction_id'')==''0'':
#方向选择全部
#方向id=0,即获取所有的视频分类(包括视频分类的id和name)
class_list=models.Classification.objects.all().values(''id'',''name'')
#如果视频分类id也为0,即全部分类,那就什么都不用做,因为已经全取出来了
ifkwargs.get(''classification_id'')==''0'':
pass
else:
#如果视频分类不是全部,过滤条件为视频分类id在[url中的视频分类id]
q[''classification_id__in'']=[class_id,]
else:
print(''方向不为0'')
#方向选择某一个方向,
#如果分类是0
ifkwargs.get(''classification_id'')==''0'':
print(''分类为0'')
#获取已选择的视频方向
obj=models.Direction.objects.get(id=int(kwargs.get(''direction_id'')))
#获取该方向的所有视频分类
class_list=obj.classification.all().values(''id'',''name'')
#获取所有视频分类对应的视频分类id
id_list=list(map(lambdax:x[''id''],class_list))
#过滤条件为视频分类idin[该方向下的所有视频分类id]
q[''classification_id__in'']=id_list
else:
#方向不为0,分类也不为0
obj=models.Direction.objects.get(id=int(kwargs.get(''direction_id'')))
class_list=obj.classification.all().values(''id'',''name'')
id_list=list(map(lambdax:x[''id''],class_list))
#过滤条件为视频分类idin[已经选择的视频分类id]
q[''classification_id__in'']=[class_id,]
print(''分类不为0'')
#当前分类如果在获取的所有分类中,则方向下的所有相关分类显示
#当前分类如果不在获取的所有分类中,
ifint(kwargs.get(''classification_id''))inid_list:
pass
else:
print(''不再,获取指定方向下的所有分类:选中的回到全部'')
url_part_list=request_path.split(''-'')
url_part_list[2]=''0''
request_path=''-''.join(url_part_list)
#视频等级id
level_id=int(kwargs.get(''level_id''))
iflevel_id==0:
pass
else:
#过滤条件增加视频等级
q[''level'']=level_id
#取出相对应的视频
video_list=models.Video.objects.filter(q).values(''title'',''summary'',''img'',''href'')
#把视频等级转化为单个标签是字典格式,整体是列表格式
ret=map(lambdax:{"id":x[0],''name'':x[1]},models.Video.level_choice)
level_list=list(ret)
returnrender(request,''video.html'',{''direction_list'':direction_list,
''class_list'':class_list,
''level_list'':level_list,
''current_url'':request_path,
"video_list":video_list})
复制代码
|
|