• 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=" 150px;height: 120px" alt="">
                        <p>{{ i.title }}</p>
                    </div>
                {% endfor %}
            </div>
    
    
        </div>
    {% endblock %}
  • 相关阅读:
    现代物流系统及其输送机构
    什么是线性插值原理 什么是双线性插值?
    Windows常见窗口样式和控件风格
    CAsyncSocket
    使用CRectTracker类进行对象动态定位
    英文自我介绍
    QQ 静态截图程序模拟实现
    使用CRectTracker类进行对象动态定位
    QQ 静态截图完善实现之改造 CRectTracker 类
    [原创] 骨骼运动变换的数学计算过程详解
  • 原文地址:https://www.cnblogs.com/xieys-1993/p/11949145.html
Copyright © 2020-2023  润新知