组合搜索: 根据特定标签内容,返回符合的数据。 效果图:
设计规划: 一、数据库表划分: 1.方向表,(运维自动化,Python开发,。。) 2.分类表,(Python,Java,C#,。) 3.多对多,方向与分类外键表, 4.视频表,(视频1,视频2,。。。) 二、表间关系: 方向表与分类表:为多对多关系, 1个方向可以有多种分类,1个分类可以同时对应多个方向。 分类表与视频表:一对多关系, 1个分类可以有多个视频。 三、表内详细设计: 方向表: class Direction(models.Model): weight = models.IntegerField(verbose_name='权重(按从大到小排列)', default=0) name = models.CharField(verbose_name='名称', max_length=32) classification = models.ManyToManyField('Classification') class Meta: db_table = 'Direction' verbose_name_plural = u'方向(视频方向)' def __str__(self): return self.name classfication为方向表(Direction)多对多关系字段; 分类表: ![]() 视频表: ![]() level为等级字段,status为视频状态字段;
具体效果: 通过对比其他同类型的搜索示例发现,他们大多数都通过URL地址来向后台传递类别 id 查询数据库,然后返回数据给前端页面。 可以发现:方向对应第一个数字,分类对应第二个数字,等级对应第三个数字。 方向的标签代码为: 当点击分类或等级时,其自身对应的id数字会发生改变,而另外两个数字id不产生变化。
设计步骤: 1.我们先设计出通过输入网页URL地址的方式,动态改变页面标签代码中的值。 设计URL选择器,正则表达式:
direction_id 为获得方向id,classfication_id为获得分类id,level_id为获得等级id 2.输入url: /video-1-2-1.html 后参数传递给 views.video()函数处理。 def video(request,*args,**kwargs): current_url = request.path #当前输入网页路径 /video-0-0-0.html direction_id = int(kwargs.get('direction_id')) #获得相应的id classfication_id = int(kwargs.get('classfication_id')) level_id = int(kwargs.get('level_id')) 接下来通过获得的id数据查询数据库信息; 此时,我们得知数据库中id字段是从1开始递增,所以我们设计当id=0 时为获得全部数据。 1.当方向为0时,表示直接从数据库获取所有的分类信息: 由于,方向字段在网页上表现为永远显示全部数据。所以设计如下 def video(request,*args,**kwargs): # ...... 省略了部分 # 获得所有方向信息: direction_list = models.Direction.objects.all().values('name','id') if direction_id != 0 : # 分类不等于0 即选择了其中一个分类, /video-1-3-1.html # 取 url相对应的分类信息(根据 方向id 进行查询,连表查询) direction = models.Direction.objects.get(id=direction_id) classfication_list = direction.classification.values('name', 'id') else: classfication_list = models.Classification.objects.all().values('name','id') #分类等于0 为 全部, 直接取全部分类数据 # 获得所有等级信息 # level_list = models.Video.level_choice ret = map(lambda x:{'name':x[1],'id':x[0]},models.Video.level_choice) level_list = list(ret) # 数据返回前端页面 return render(request,'video.html',{'direction_list':direction_list,'class_list':classfication_list,'level_list':level_list,'current_url':current_url}) 其中,等级信息,存放在video表中的level字段中,以元组形式存放,为了统一我们将(元组,..)的形式 => [字典,..],使用了map()函数 向前端页面返回了,方向,分类,等级的数据和当前url地址。 /video-1-3-1.html。 核心:前端接收到当前url地址后,通过模版语言simple_tag,动态的构造a标签的href属性,即可表现为当改变url时,标签href也同时发生改变 前端页面: <div> {% for item in direction_list %} {% simple_tag函数 current_url item %} {% endfor %} </div> 3.设计simple_tag函数。 需要在项目app下创建 templatetags包, 然后自定义一个文件 xx.py from django import template from django.utils.safestring import mark_safe register = template.Library() @register.simple_tag def action1(current_url, item): url_part_list = current_url.split('-') # 如果当前url中第一个位置 video-2-0-0.html if str(item['id']) == url_part_list[1]: temp = "<a href='%s' class='active'>%s</a>" else: temp = "<a href='%s'>%s</a>" url_part_list[1] = str(item['id']) ur_str = '-'.join(url_part_list) temp = temp %(ur_str, item['name']) return mark_safe(temp) 得到了一个处理 方向 标签的模板函数,方向、等级标签的处理方式同上,只是url切割的位置稍有不同! ![]() ![]() 然后再设计一个在前端同时输出, "全部" 的simple_tag函数 ![]() ![]() 为了降低simple_tag代码过于冗余,我们用if..else统一归类成一个函数: ![]() ![]() 至此,我们已经完成了 页面上输出全部的方向、分类、等级的数据,以及通过url地址改变动态修改了a标签href代码和添加了选中时特效。我们还需要添加限制规则,规定当 方向 改变时,出现不同的分类! 4.进一步考虑添加规则! 当输入的url中,方向id等于0 时, => 显示全部分类, video-0-0-2.html 不等于0 时,=> if 分类id等于0 => 分类根据 方向id 取出数据 不等于0 => 分类根据 方向id 取出数据 当先输入的url中,分类id没有出现在通过查询获得的分类id时,需要把分类id 置为0。 ![]() 5.最后考虑输出视频数据: 当方向、分类、等级id都为0时,输出全部的视频; 当方向=0、分类!=0时,根据分类id查询数据库 当方向!=0、分类=0时,根据分类id查询数据库 当方向!=0、分类!=0时,根据分类id查询数据库 当等级!=0时, 根据分类id,等级id查询数据库 ![]() 注意: 查询时,可以通过构造一个字典的方式添加查询条件,返回最终结果。 q = {} ret = models.X.objects.filter(**q).values('..,..')
最终效果图: 完整代码: ![]() ![]() ![]() ![]()
|
|