django實現組合查詢

前言

  在瀏覽淘寶網頁時,在找不到中意的商品時,在頁面頂部有諸多的搜索條件供於點擊聯合查詢。
html

  那麼,接下來能夠作一個小DEMO,如圖...web

     

Model表建立,Url映射,Views函數處理

根據上圖,視頻方向與視頻分類是多對多的關係,視頻分類與視頻信息是一對多的關係,難度級別是單一的查詢條件(與以前倆者並沒有關係)django

Models.py以下:
ide

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 = '方向(視頻方向)'

    def __str__(self):
        return self.name


class Classification(models.Model):
    """ 視頻分類表 """
    weigth = models.IntegerField(verbose_name='權重(從大到小)', default=0)
    name = models.CharField(verbose_name='名稱', max_length=32)

    class Meta:
        db_table = 'Classification'
        verbose_name_plural = '分類(視頻分類)'

    def __str__(self):
        return self.name


class Video(models.Model):
    """ 視頻信息表 """
    status_choice = (
        (0, '下線'),
        (1, '上線'),
    )
    level_choice = (
        (1, '初級'),
        (2, '中級'),
        (3, '高級'),
    )
    status = models.IntegerField(verbose_name='狀態', choices=status_choice, default=1)
    level = models.IntegerField(verbose_name='級別', choices=level_choice, default=1)
    classification = models.ForeignKey('Classification', null=True, blank=True)

    weight = models.IntegerField(verbose_name='權重(從大到小)', default=0)
    title = models.CharField(verbose_name='標題', max_length=32)
    summary = models.CharField(verbose_name='簡介', max_length=32)
    img = models.ImageField(verbose_name='圖片', upload_to='./static/images/Video/')
    href = models.CharField(verbose_name='視頻地址', max_length=255)

    create_date = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = 'Video'
        verbose_name_plural = '視頻'

    def __str__(self):
        return self.title
models.py

Url映射獲取搜索條件以下:函數

在url路由配置中,能夠有命名的傳參獲得 視頻方向ID 視頻分類ID 視頻難度ID 三個條件
url

from django.conf.urls import url
from django.contrib import admin
from web_manage import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    url(r'videos-(?P<direction_id>\d+)-(?P<classification_id>\d+)-(?P<level>\d+).html',views.videos)
]
urls.py

Views函數(video)處理以下:spa

A在視圖函數中,獲取到 方向、分類、難度三個值,並建立搜索條件的字典code

    """
    :param request: 
    :param args: 
    :param kwargs: {'direction_id': '0','classification_id': '0','level': '0'}
    :return: 
    """
    search = {}  # 構建搜索條件字典
    for k, v in kwargs.items():  
        temp = int(v)
        kwargs[k] = temp

    # 構造搜索條件
    direction_id = kwargs.get('direction_id')
    classification_id = kwargs.get('classification_id')
    level = kwargs.get('level')
View Code

B、HTML頁面顯示視頻

  • 在HTML頁面,視頻方向的選項一直存在;
  • 視頻分類在視頻方向的選擇項爲所有時則所有展示,當視頻方向(所有除外)爲指定項時,則顯示指定視頻方向下的視頻分類;
  • 難度依舊顯示全部選項。

C、搜索條件構建htm

a、若是未指定方向(所有對應的ID爲0)

# 若是未指定視頻方向
if direction_id == 0:
    # 視頻分類則獲取所有
    classification = models.Classification.objects.all()
    # 若是未指定視頻分類,搜索字典無此項 默認查詢條件應根據難度(無分類查詢)
    if classification_id == 0:
        pass
    # 若是指定視頻分類
    else:
        # 搜索字典構建的分類ID 爲 url 取到的分類ID
        search['classification_id'] = classification_id
View Code

b、若是指定視頻方向(所有除外)

  • 應獲取指定視頻方向下的視頻分類
  • 視頻方向下沒有視頻分類的狀況,列舉爲
# 若是指定視頻方向
else:
    # 獲取當前指定視頻方向對象
    direction_obj = models.Direction.objects.filter(id=direction_id).first()
    # 獲取視頻方向對應的全部視頻分類
    classification = direction_obj.classification.all()
    # 獲取視頻方向對應的全部視頻分類的的ID
    vlist = direction_obj.classification.all().values_list('id')

    # 若是視頻方向沒有分類
    if not vlist:
        classification_list = []
    # 若是視頻方向有分類
    else:
        classification_list = list(zip(*vlist))[0]  # 注意zip的用法
View Code

  若是指定了視頻方向,視頻分類簡單分爲倆種狀況

  • 視頻分類選項爲所有(所有對應ID爲0)
  • 視頻分類被指定(特殊狀況:若是視頻分類被指定更換視頻方向)

    一、視頻分類存在於更替的視頻方向的狀況下,則分類不變

    二、視頻分類不存在於更替的視頻方向的狀況下,則分類選中所有

        # 若是url分類ID爲0   搜索條件 分類則爲 指定方向下的全部分類
        if classification_id == 0:
            # 搜索字典 特殊 賦值   了不得的下劃線之 __in
            search['classification_id__in'] = classification_list
        # 指定方向下 指定了分類
        else:
            # 若是 分類ID 存在於 指定方向的 全部分類ID內
            if classification_id in classification_list:
                search['classification_id'] = classification_id
            # 若是更替指定方向,分類不變 不存在於 該方向的全部分類內
            else:
                # 即默認指定全部
                kwargs['classification_id'] = 0
                search['classification_id__in'] = classification_list
View Code

c、難度級別篩選

    # 視頻級別
    # 若是未指定難度級別
    if level == 0:
        pass
    # 難度級別被指定
    else:
        search['level'] = level
View Code

d、查詢

video_list = models.Video.objects.filter(**search)

Html生成

<div class="search">
                <div class="filter" auto-id="search_filter">
                    <!-- 方向類選取 -->
                    <dl class="clearfix">
                        <dt>方向:</dt>
                        <dd class="" id="purpose_status">
                            {% if kwargs.direction_id == 0 %}
                                <a class="selected" href='/videos-0-{{ kwargs.classification_id }}-{{ kwargs.level }}.html'>所有</a>
                            {% else %}
                                <a href='/videos-0-{{ kwargs.classification_id }}-{{ kwargs.level }}.html'>所有</a>
                            {% endif %}
                            {% for item in direction %}
                                {% if item.id == kwargs.direction_id %}
                                    <a class="selected" href="/videos-{{ item.id }}-{{ kwargs.classification_id }}-{{ kwargs.level }}.html">{{ item.name }}</a>
                                {% else %}
                                    <a href="/videos-{{ item.id }}-{{ kwargs.classification_id }}-{{ kwargs.level }}.html">{{ item.name }}</a>
                                {% endif %}
                            {% endfor %}
                        </dd>
                    </dl>

                    <dl class="clearfix">
                        <dt>分類:</dt>
                        <dd id="material_status">
                            {% if kwargs.classification_id == 0 %}
                                <a class="selected" href="/videos-{{ kwargs.direction_id }}-0-{{ kwargs.level }}.html">所有</a>
                            {% else %}
                                <a href="/videos-{{ kwargs.direction_id }}-0-{{ kwargs.level }}.html">所有</a>
                            {% endif %}
                            {% for item in classification %}
                                {% if item.id == kwargs.classification_id  %}
                                    <a class="selected" href="/videos-{{ kwargs.direction_id }}-{{ item.id }}-{{ kwargs.level }}.html">{{ item.name }}</a>
                                {% else %}
                                    <a href="/videos-{{ kwargs.direction_id }}-{{ item.id }}-{{ kwargs.level }}.html">{{ item.name }}</a>
                                {% endif %}
                            {% endfor %}
                        </dd>
                    </dl>

                    <dl class="clearfix">
                        <dt>難度:</dt>
                        <dd id="surface_status">
                            {% if kwargs.level == 0 %}
                                <a class="selected" href="/videos-{{ kwargs.direction_id }}-{{ kwargs.classification_id }}-0.html">所有</a>
                            {% else %}
                                <a href="/videos-{{ kwargs.direction_id }}-{{ kwargs.classification_id }}-0.html">所有</a>
                            {% endif %}
                            {% for item in level %}
                                {% if item.0 == kwargs.level %}
                                    <a class="selected" href="/videos-{{ kwargs.direction_id }}-{{ kwargs.classification_id }}-{{ item.0 }}.html">{{ item.1 }}</a>
                                {% else %}
                                    <a href="/videos-{{ kwargs.direction_id }}-{{ kwargs.classification_id }}-{{ item.0 }}.html">{{ item.1 }}</a>
                                {% endif %}
                            {% endfor %}
                        </dd>
                    </dl>
                </div>
            </div>
View Code
相關文章
相關標籤/搜索