django使用url路径组合搜索

Posted xieys-1993

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django使用url路径组合搜索相关的知识,希望对你有一定的参考价值。

组合搜索其实就是网页中组合多个条件,对数据库中进行查询,并且将结果显示在页面中,如下:

技术图片

 

 可以看到我们红框部分,是根据URL来做组合搜索的

这里是以视频为例,

video-1-1-0.html 后面三位数字的含义
第一位数字: 视频方向 id
第二位数字: 视频类型 id
第三位数字: 视频难度 id

代码分析:

url.py部分,我们需要用正则匹配

re_path(^video-(?P<direction_id>d+)-(?P<classes_id>d+)-(?P<level_id>d+).html,views.video)

#这里有分为3组都为数字的数据direction_id(方向ID)、classes_id(类型ID)、level_id(级别难度id),会直接作为参数传递到views.video函数
解释下上面正则

1、这里的(?P<name>...) 和普通的(?...):
基本类似。区别在于,此处由于是给此group命名了,所有后续(同一正则表达式内和搜索后得到的Match对象中),都可以通过此group的名字去引用此group

2、同一正则表达式内,每个group组名是唯一的,不能重复

 

表结构 models.py

技术图片
 1 class Direction(models.Model):
 2     ‘‘‘
 3     视频方向
 4     ‘‘‘
 5     state_choice = (
 6         (0, 展示),
 7         (1, 不展示),
 8     )
 9     name = models.CharField(max_length=32,verbose_name=视频方向)
10     classes = models.ManyToManyField(Classes)
11     state = models.SmallIntegerField(choices=state_choice,default=0,verbose_name=方向状态)
12 
13     class Meta:
14         db_table = direction
15         verbose_name_plural = 视频方向
16 
17     def __str__(self):
18         return self.name
19 
20 class Classes(models.Model):
21     ‘‘‘
22     视频类别
23     ‘‘‘
24     state_choice = (
25         (0, 展示),
26         (1, 不展示),
27     )
28     name = models.CharField(max_length=32,verbose_name=视频分类)
29     state = models.SmallIntegerField(choices=state_choice,default=0,verbose_name=分类状态)
30 
31     class Meta:
32         db_table = classes
33         verbose_name_plural = 视频分类
34 
35     def __str__(self):
36         return self.name
37 
38 class Video(models.Model):
39     ‘‘‘
40     视频信息
41     ‘‘‘
42     state_choice = (
43         (0, 展示),
44         (1, 不展示),
45     )
46     level = (
47         (1,初级),
48         (2,中级),
49         (3,高级),
50     )
51     title = models.CharField(max_length=32,blank=True,verbose_name=视频标题)
52     level_id = models.SmallIntegerField(choices=level,default=1,verbose_name=视频级别)
53     state = models.SmallIntegerField(choices=state_choice,default=0,verbose_name=视频状态)
54     href = models.CharField(max_length=256,verbose_name=视频链接)
55     jianjie = models.CharField(max_length=256,verbose_name=视频简介)
56     img = models.ImageField(upload_to=./static/img/video/,null=True,verbose_name=视频图片)
57     classes = models.ForeignKey(Classes,on_delete=models.CASCADE)
58 
59     class Meta:
60         db_table = video
61         verbose_name_plural = 视频信息
62 
63     def __str__(self):
64         return self.title
models.py

视频方向表和视频类别表是多对多关系

视频类别表和视频信息表是一对多关系

 

主逻辑 views.py

def video(request,*args,**kwargs):
    logo = models.Logo.objects.all().first()
    menu_nav = models.MenuNav.objects.all().order_by(-width)

    ‘‘‘
    这里从kwargs 获取url上面匹配到的数字,用组名取值
    ‘‘‘
    direction_id = int(kwargs[direction_id])
    classes_id = int(kwargs[classes_id])
    level_id = int(kwargs[level_id])

    #定义一个空字典,用于最后结果的组合查询条件
    contents = {}

    #视频方向是永远不会发生变化的,所以这里直接从数据库中取出来
    direction_ls = models.Direction.objects.filter(state=0).values(id,name)

    ‘‘‘
    判断url上的方向id 是否为 0 或者 方向id 不在 取出来的视频方向id里面:
        就把url传过来的方向ID赋值为0(这里是当后面条件成立时有用),
        获取所有的类型,然后判断 url 传过来的 类型id 是否为0 或者 类型id 不在取出来的类型id里面: 
            就把url传过来的类型id赋值为0 (同上),
            然后把所有的类型ID 赋值给查询条件 contents[‘classes_id__in‘] ,这里的classes_id__in 键值,是查询时候的键值
        否则(类型id不为0,并且在取出来的类型id列表里面):
            就把url取出来的类型id 赋值为 contents[‘classes_id‘] 这里的classes_id 键值,是查询时候的键值
    否则(方向id不为0,并且在取出来的方向id列表里面):
        首先取出对应url方向id的所有类型
        然后判断 url 传过来的 类型id 是否为0 或者 类型id 不在取出来的类型id里面: 
            就把url传过来的类型id赋值为0 (同上),
            然后把所有的类型ID 赋值给查询条件 contents[‘classes_id__in‘] ,这里的classes_id__in 键值,是查询时候的键值
        否则(类型id不为0,并且在取出来的类型id列表里面):
            就把url取出来的类型id 赋值为 contents[‘classes_id‘] 这里的classes_id 键值,是查询时候的键值
            
    
    
    ‘‘‘
    if direction_id == 0 or direction_id not in [i[id] for i in direction_ls]:
        direction_id = 0
        class_ls = models.Classes.objects.all().values_list(id,name)
        if classes_id == 0 or classes_id not in [i[0] for i in class_ls]:
            classes_id = 0
            contents[classes_id__in] = [i[0] for i in class_ls]
        else:
            contents[classes_id] = classes_id
    else:
        class_ls = models.Direction.objects.filter(id=direction_id).values_list(classes__id,classes__name)
        if classes_id == 0 or classes_id not in [i[0] for i in class_ls]:
            classes_id = 0
            contents[classes_id__in] = [i[0] for i in class_ls]
        else:

            contents[classes_id] = classes_id

    level_ls = models.Video.level
    if level_id != 0 :
        contents[level_id] = level_id
    contents[state] = 0
    result = models.Video.objects.filter(**contents)

    return render(request,video.html,{
        menu_nav:menu_nav,
        Logo:logo,
        direction_id:direction_id,
        classes_id:classes_id,
        level_id:level_id,
        direction_ls:direction_ls,
        class_ls:class_ls,
        level_ls:level_ls,
        result:result
                                        })

 

前端 video.html,这里就没有截取样式的图了

{% extends base.html %}
{% block head_content %}{% endblock %}
{% block content %}
    <div class="video_select">


         <ul>
         <p>方向:</p>
        {% if direction_id == 0  %}
            <li><a class="active" href="video-0-{{ classes_id }}-{{ level_id }}.html">全部</a></li>
        {% else %}
            <li><a  href="video-0-{{ classes_id }}-{{ level_id }}.html">全部</a></li>
        {% endif %}
        {% for i in direction_ls %}
            {% if i.id == direction_id %}
                <li><a  class="active" href="video-{{ i.id }}-{{ classes_id }}-{{ level_id }}.html">{{ i.name }}</a></li>
            {% else %}
                <li><a  href="video-{{ i.id }}-{{ classes_id }}-{{ level_id }}.html">{{ i.name }}</a></li>
            {% endif %}
        {% endfor %}
         </ul>

     <ul >
     <p>分类:</p>
         {% if classes_id == 0  %}
            <li><a class="active" href="video-{{ direction_id }}-0-{{ level_id }}.html">全部</a></li>
        {% else %}
            <li><a  href="video-{{ direction_id }}-0-{{ level_id }}.html">全部</a></li>
        {% endif %}
         {% for i in class_ls %}
            {% if i.0 == classes_id %}
                <li><a  class="active" href="video-{{ direction_id }}-{{ i.0 }}-{{ level_id }}.html">{{ i.1 }}</a></li>
            {% else %}
                <li><a  href="video-{{ direction_id }}-{{ i.0 }}-{{ level_id }}.html">{{ i.1 }}</a></li>
            {% endif %}
        {% endfor %}
    </ul>
    <ul>
        <p>难度:</p>
        {% if level_id == 0  %}
            <li><a class="active" href="video-{{ direction_id }}-{{ classes_id }}-0.html">全部</a></li>
        {% else %}
            <li><a  href="video-{{ direction_id }}-{{ classes_id }}-0.html">全部</a></li>
        {% endif %}
         {% for i in level_ls %}
            {% if i.0 == level_id %}
                <li><a  class="active" href="video-{{ direction_id }}-{{ classes_id }}-{{ i.0}}.html">{{ i.1 }}</a></li>
            {% else %}
                <li><a  href="video-{{ direction_id }}-{{ classes_id }}-{{ i.0 }}.html">{{ i.1 }}</a></li>
            {% endif %}
        {% endfor %}
    </ul>
    </div>

    <div class="video-content">
        <div class="row">
            {% for i in result %}
                <div class="col-xs-3">
                    <img src="{{ i.img }}"  style="width: 150px;height: 120px" alt="">
                    <p>{{ i.title }}</p>
                </div>
            {% endfor %}
        </div>


    </div>
{% endblock %}

 

 

 

 

以上是关于django使用url路径组合搜索的主要内容,如果未能解决你的问题,请参考以下文章

Django实现组合搜索的方法示例

Django实现组合搜索的方法示例

Django实现组合搜索

django 组合搜索

django中“url映射规则”和“服务端响应顺序”

django 2.2.5 URL 路径中的 URL 正则表达式