分享

【Python之路】特别篇

 highoo 2019-03-20

组合搜索:

  根据特定标签内容,返回符合的数据。

效果图:

 

设计规划:

一、数据库表划分:

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)多对多关系字段;

分类表:

View Code

视频表:

View Code

level为等级字段,status为视频状态字段;

 

具体效果:

通过对比其他同类型的搜索示例发现,他们大多数都通过URL地址来向后台传递类别 id 查询数据库,然后返回数据给前端页面。

可以发现:方向对应第一个数字,分类对应第二个数字,等级对应第三个数字。

方向的标签代码为:

当点击分类或等级时,其自身对应的id数字会发生改变,而另外两个数字id不产生变化。

 

设计步骤:

1.我们先设计出通过输入网页URL地址的方式,动态改变页面标签代码中的值。

设计URL选择器,正则表达式:

1
url(r'^video-(?P<direction_id>\d+)-(?P<classfication_id>\d+)-(?P<level_id>\d+).html', views.video),

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切割的位置稍有不同!

前端video.html
newtag.py

然后再设计一个在前端同时输出, "全部" 的simple_tag函数

前端video.html
newtag.py

为了降低simple_tag代码过于冗余,我们用if..else统一归类成一个函数:

前端video.html
newtag.py

至此,我们已经完成了 页面上输出全部的方向、分类、等级的数据,以及通过url地址改变动态修改了a标签href代码和添加了选中时特效。我们还需要添加限制规则,规定当 方向 改变时,出现不同的分类!

4.进一步考虑添加规则!

当输入的url中,方向id等于0 时,  => 显示全部分类,  video-0-0-2.html

          不等于0 时,=>  if  分类id等于0  =>  分类根据 方向id 取出数据

                        不等于0 =>  分类根据 方向id 取出数据   当先输入的url中,分类id没有出现在通过查询获得的分类id时,需要把分类id 置为0。

views.video()

5.最后考虑输出视频数据:

当方向、分类、等级id都为0时,输出全部的视频;

当方向=0、分类!=0时,根据分类id查询数据库

当方向!=0、分类=0时,根据分类id查询数据库

当方向!=0、分类!=0时,根据分类id查询数据库

当等级!=0时, 根据分类id,等级id查询数据库                                

views.video()

注意: 查询时,可以通过构造一个字典的方式添加查询条件,返回最终结果。

q = {}
ret = models.X.objects.filter(**q).values('..,..')

 

最终效果图:

完整代码:

后台 views.py
后台 models.py
后台 newtag.py
前端 video.html

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约