1. 程式人生 > >django中實現組合搜索

django中實現組合搜索

關系 list == choice ctype ive 代碼 key sel

一.簡介

# 組合搜索
# 技術方向:自動化,測試,運維,前端
# 分類:Python Linux JavaScript OpenStack Node.js GO
# 級別:初級 中級 高級 骨灰級

有4張表:
Direction(技術方向標),Classification(技術分類表),Level(難度級別表),Video(視頻表)

它們的關系是:
Direction與Classification多對多關系
Video與Classification,Level是一對多關系

最終要實現的結果如下圖:

技術分享圖片


二.models代碼

class Direction(models.Model):
    
""" 技術方向:自動化,測試,運維,前端 """ name = models.CharField(verbose_name=名稱, max_length=32) classification = models.ManyToManyField(Classification) class Meta: # 重命名表名,不要自動添加的app名 db_table = Direction verbose_name_plural = 方向(視頻方向) def __str__
(self): return self.name class Classification(models.Model): """ 分類:Python Linux JavaScript OpenStack Node.js GO """ name = models.CharField(verbose_name=名稱, max_length=32) class Meta: db_table = Classification verbose_name_plural = 分類(視頻分類)
def __str__(self): return self.name class Level(models.Model): title = models.CharField(max_length=32) class Meta: db_table = Level verbose_name_plural = 難度級別 def __str__(self): return self.title class Video(models.Model): status_choice = ( (1, 下線), (2, 上線), ) status = models.IntegerField(verbose_name=狀態, choices=status_choice, default=1) level = models.ForeignKey(Level) 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/‘) img = models.CharField(verbose_name=圖片, max_length=32) href = models.CharField(verbose_name=視頻地址, max_length=256) create_date = models.DateTimeField(auto_now_add=True) class Meta: db_table = Video verbose_name_plural = 視頻 def __str__(self): return self.title

三.url路由代碼

urlpatterns=[
    url(r^admin,admin.site.urls),
    #利用的是有名分組的方法,分別獲取不同的id
    url(r^video-(?P<direction_id>(\d+))-(?P<classification_id>(\d+))-(?P<level_id>(\d+)).html$, views.video,
        name=video)
]

四.視圖代碼

def video(request,*args,**kwargs):
    condition = {}

    for k, v in kwargs.items():
        temp = int(v)
        kwargs[k] = temp
    print(kwargs) # (?P<direction_id>(\d+))-(?P<classification_id>(\d+))-(?P<level_id>(\d+))
    # 構造查詢字典
    direction_id = kwargs.get(direction_id)
    classification_id = kwargs.get(classification_id)
    level_id = kwargs.get(level_id)
    # 獲取所有的技術方向
    direction_list = models.Direction.objects.all()
    # 當沒有選擇技術方向時,就獲取所有分類
    if direction_id == 0:
        class_list = models.Classification.objects.all()
        # 當沒有選擇分類時,不做什麽
        if classification_id == 0:
            pass
        else:
            # 否則就將分類id放入字典
            condition[classification_id] = classification_id
    else:
        # 當選擇了技術方向id時,查詢出該技術方向下的所有分類
        direction_obj = models.Direction.objects.filter(id=direction_id).first()
        class_list = direction_obj.classification.all()
        # 只獲取該方向下的分類id
        vlist = direction_obj.classification.all().values_list(id)
        # 下面的代碼為了生成condition是傳入的一對多查詢id,如:{‘classification_id__in‘: (1, 2, 3), ‘level_id‘: 1}
        if not vlist:
            classification_id_list = []
        else:
            # 將vlist轉換成列表
            classification_id_list = list(zip(*vlist))[0]

        if classification_id == 0:
            condition[classification_id__in] = classification_id_list
        else:
            if classification_id in classification_id_list:
                condition[classification_id] = classification_id
            else:
                #指定技術方向:[1,2,3]   分類:5
                kwargs[classification_id] = 0
                condition[classification_id__in] = classification_id_list

    if level_id == 0:
        pass
    else:
        condition[level_id] = level_id

    level_list = models.Level.objects.all()
    video_list = models.Video.objects.filter(**condition)
    # 技術方向的queryset對象列表
    print(direction_list)
    # 分類的queryset對象列表
    print(class_list)
    # 等級的queryset對象列表
    print(level_list)
    # video的queryset對象列表
    print(video_list)
    # 技術方向的id,分類的id,等級的id組成的字典
    print(kwargs)
    return render(
        request,
        video.html,
        {
            direction_list:direction_list,
            class_list:class_list,
            level_list:level_list,
            video_list:video_list,
            kwargs:kwargs,
        }
    )

五.模板代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .condition a {
            display: inline-block;
            padding: 5px 8px;
            border: 1px solid #dddddd;
        }

        .condition a.active {
            background-color: coral;
            color: white;
        }
    </style>
</head>
<body>
<div class="condition">
    <h1>篩選</h1>
    <div>
        {% if kwargs.direction_id == 0 %}
            {#反向解析#}
            <a href="{% url "video" direction_id=0 classification_id=kwargs.classification_id level_id=kwargs.level_id %}"
               class="active">全部</a>
        {% else %}
            <a href="{% url "video" direction_id=0 classification_id=kwargs.classification_id level_id=kwargs.level_id %}">全部</a>
        {% endif %}
        {% for item in direction_list %}
            {% if item.id == kwargs.direction_id %}
                <a href="{% url "video" direction_id=item.id classification_id=kwargs.classification_id level_id=kwargs.level_id %}"
                   class="active">{{ item.name }}</a>
            {% else %}
                <a href="{% url "video" direction_id=item.id classification_id=kwargs.classification_id level_id=kwargs.level_id %}">{{ item.name }}</a>
            {% endif %}
        {% endfor %}
    </div>
    <div>
        {% if kwargs.classification_id == 0 %}
            <a href="/video-{{ kwargs.direction_id }}-0-{{ kwargs.level_id }}.html" class="active">全部</a>
        {% else %}
            <a href="/video-{{ kwargs.direction_id }}-0-{{ kwargs.level_id }}.html">全部</a>
        {% endif %}
        {% for item in class_list %}
            {% if item.id == kwargs.classification_id %}
                <a href="/video-{{ kwargs.direction_id }}-{{ item.id }}-{{ kwargs.level_id }}.html"
                   class="active">{{ item.name }}</a>
            {% else %}
                <a href="/video-{{ kwargs.direction_id }}-{{ item.id }}-{{ kwargs.level_id }}.html">{{ item.name }}</a>
            {% endif %}
        {% endfor %}
    </div>
    <div>
        {% if kwargs.level_id == 0 %}
            <a href="/video-{{ kwargs.direction_id }}-{{ kwargs.classification_id }}-0.html" class="active">全部</a>
        {% else %}
            <a href="/video-{{ kwargs.direction_id }}-{{ kwargs.classification_id }}-0.html">全部</a>
        {% endif %}
        {% for item in level_list %}
            {% if item.id == kwargs.level_id %}
                <a href="/video-{{ kwargs.direction_id }}-{{ kwargs.classification_id }}-{{ item.id }}.html"
                   class="active">{{ item.title }}</a>
            {% else %}
                <a href="/video-{{ kwargs.direction_id }}-{{ kwargs.classification_id }}-{{ item.id }}.html">{{ item.title }}</a>
            {% endif %}
        {% endfor %}
    </div>

</div>
<div>
    <h1>結果</h1>
    {% for row in video_list %}
        <div>{{ row.title }}</div>
    {% endfor %}
</div>
</body>
</html>

django中實現組合搜索