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 %}

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM