配色: 字号:
django多条件筛选搜索
2016-10-07 | 阅:  转:  |  分享 
  
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})

复制代码

献花(0)
+1
(本文系thedust79首藏)