model.py

# 视频方向
class Direction(models.Model):
    '''
    方向:自动化,测试,运维,前端
    '''
    name = models.CharField(verbose_name='名称', max_length=32)

    classification = models.ManyToManyField('Classification')

    class Meta:
        db_table = 'Direction'
        verbose_name = '方向(视频方向)'

    def __str__(self):
        return self.name


# 视频分类
class Classification(models.Model):
    '''
    分类:Python,Linux,JavaScript,OpenStack,Node.js
    '''
    name = models.CharField(verbose_name='名称', max_length=32)

    class Meta:
        db_table = 'Classification'
        verbose_name = '分类(视频分类)'

    def __str__(self):
        return self.name


# 难度等级
class Level(models.Model):
    title = models.CharField(max_length=32)

    class Meta:
        verbose_name = '难度级别'

    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', on_delete=models.CASCADE)
    classification = models.ForeignKey('Classification', null=True, blank=True, on_delete=models.CASCADE)

    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=256)

    create_date = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = '视频'

    def __str__(self):
        return self.title

View Code

 

一对多的筛选:

URL:

re_path('video-(?P<classification_id>(\d+))-(?P<level_id>(\d+))-(?P<status>(\d+)).html/', views.video),

View:

def video(request, *args, **kwargs):
    # 创建一个空字典存放筛选信息
    condition = {
        # 'level_id': 0,
        # 'classification_id': 0,
    }

    # 循环遍历传递过来的数据kwargs
    for k, v in kwargs.items():
        # 字符串类型转数字类型
        temp = int(v)
        # 更新kwargs字典
        kwargs[k] = temp
        # 如果传递过来的是非0数字(若传过来的是0,则不筛选,显示全部)
        if temp:
            # 存放筛选信息
            condition[k] = temp

    # 获取所有的视频分类
    class_list = models.Classification.objects.all()
    # 获取所有的视频级别
    level_list = models.Level.objects.all()
    # 获取所有的视频状态
    status_list = list(map(lambda x: {'id': x[0], 'name': x[1]}, models.Video.status_choice))

    # 获取符合筛选条件的视频列表
    video_list = models.Video.objects.filter(**condition)

    return render(
        request,
        'video.html',
        {
            'class_list': class_list,
            'level_list': level_list,
            'status_list': status_list,
            'kwargs': kwargs,
            'video_list': video_list,

        }
    )

HTML

<style>
        .condition a{
            display: inline-block;
            padding: 5px 8px;
            border: 1px solid #dddddd;
        }

        .condition a.active{
            background-color: coral;
            color: white;
        }
    </style>

<body>
    <div class="condition">
        <h1>筛选条件</h1>
{#筛选条件  -   分类#}
        <div>
            {% if kwargs.classification_id == 0 %}
                <a href="/video-0-{{ kwargs.level_id }}-{{ kwargs.status }}.html" class="active">全部</a>
            {% else %}
                <a href="/video-0-{{ kwargs.level_id }}-{{ kwargs.status }}.html">全部</a>
            {% endif %}

            {% for item in class_list %}
                {% if item.id == kwargs.classification_id %}
                    <a href="/video-{{ item.id }}-{{ kwargs.level_id }}-{{ kwargs.status }}.html" class="active">{{ item.name }}</a>
                {% else %}
                    <a href="/video-{{ item.id }}-{{ kwargs.level_id }}-{{ kwargs.status }}.html">{{ item.name }}</a>
                {% endif %}
            {% endfor %}
        </div>
{#筛选条件  -   难度级别#}
        <div>
            {% if kwargs.level_id == 0 %}
                <a href="/video-{{ kwargs.classification_id }}-0-{{ kwargs.status }}.html" class="active">全部</a>
            {% else %}
                <a href="/video-{{ kwargs.classification_id }}-0-{{ kwargs.status }}.html">全部</a>
            {% endif %}

            {% for item in level_list %}
                {% if item.id == kwargs.level_id %}
                    <a href="/video-{{ kwargs.classification_id }}-{{ item.id }}-{{ kwargs.status }}.html" class="active">{{ item.title }}</a>
                {% else %}
                    <a href="/video-{{ kwargs.classification_id }}-{{ item.id }}-{{ kwargs.status }}.html">{{ item.title }}</a>
                {% endif %}
            {% endfor %}
        </div>
{#筛选条件  -   上下线状态#}
        <div>
            {% if kwargs.status == 0 %}
                <a href="/video-{{ kwargs.classification_id }}-{{ kwargs.level_id }}-0.html" class="active">全部</a>
            {% else %}
                <a href="/video-{{ kwargs.classification_id }}-{{ kwargs.level_id }}-0.html">全部</a>
            {% endif %}

            {% for status in status_list %}
                {% if status.id == kwargs.status %}
                    <a href="/video-{{ kwargs.classification_id }}-{{ kwargs.level_id }}-{{ status.id }}.html" class="active">{{ status.name }}</a>
                {% else %}
                    <a href="/video-{{ kwargs.classification_id }}-{{ kwargs.level_id }}-{{ status.id }}.html">{{ status.name }}</a>
                {% endif %}
            {% endfor %}

        </div>
    </div>
    <div>
        <h1>筛选结果</h1>
        {% for video in video_list %}
            <div>
                {{ video.title }}
            </div>
        {% endfor %}
    </div>
</body>

 

 

多对多的筛选:

URL

re_path('video2-(?P<direction_id>(\d+))-(?P<classification_id>(\d+))-(?P<level_id>(\d+)).html/', views.video2,name='video2'),

View:

'''
        如果:方向direction_id = 0 即所有方向
            则列出所有的分类
            如果:分类classification_id = 0:
                则列出所有的视频
            如果:分类classification_id != 0:
                则列出该类别的所有视频
                condition['classification_id'] = classification_id

        如果:方向direction_id !=0 即指定方向
            则列出该方向下的所有分类
            如果:分类classification_id = 0:
                则列出该方向下的所有分类[1,2,3,4]的视频
                condition['classification_id__in'] = [1,2,3,4]

            如果:分类classification_id != 0:
                获取当前方向下的所有分类[1,2,3,4]
                判定classification_id是否在该方向下的所有分类中[1,2,3,4]
                如果在:
                    则列出该方向下的该类别的所有视频
                    condition['classification_id'] = classification_id
                如果不在:
                    则列出该方向下的所有类别的所有视频
                    condition['classification_id__in'] = [5,6]
    '''

思路

def video2(request, *args, **kwargs):
    # 创建一个空字典存放筛选信息
    condition = {}
    # 循环遍历传递过来的数据kwargs
    for k, v in kwargs.items():
        # 字符串类型转数字类型
        temp = int(v)
        # 更新kwargs字典
        kwargs[k] = temp

    print(kwargs)  # (?P<direction_id>(\d+))-(?P<classification_id>(\d+))-(?P<level_id>(\d+))
    # 构造查询字典
    # 从kwargs获取方向id、分类id、级别id
    direction_id = kwargs['direction_id']
    classification_id = kwargs['classification_id']
    level_id = kwargs['level_id']

    # 获取所有的方向
    direction_list = models.Direction.objects.all()

    # 如果方向id为0,则显示所有的分类
    if direction_id == 0:
        # 获取所有的分类
        class_list = models.Classification.objects.all()

        # 如果分类id为0,则不添加分类的筛选条件,显示所有的视频
        if classification_id == 0:
            pass
        else:
            # 如果分类id不为0,则添加分类的筛选条件:classification_id,显示该分类id下的所有视频
            condition['classification_id'] = classification_id

    # 如果方向id不为0,则显示特定方向的所有分类
    else:
        # 获取特定的方向对象 QuerySet[obj]
        direction_obj = models.Direction.objects.filter(id=direction_id).first()

        # 获取特定方向下的所有分类对象 QuerySet[obj,...]
        class_list = direction_obj.classification.all()

        # 获取特定方向下的所有分类对象的id QuerySet[(id1,),(id2),...]
        classification_ids = direction_obj.classification.all().values_list('id')

        # 如果该特定方向下的分类对象为空
        if not classification_ids:
            # 则类别筛选条件为空列表
            classification_id_list = []

        # 如果该特定方向下的分类对象不为空
        else:
            # 将QuerySet[(id1,id2),...]转换为列表[(id1,id2,...)]
            # 则类别筛选条件为(id1,id2,...)
            classification_id_list = list(zip(*classification_ids))[0]

        # 如果类别为0 则显示特定方向的全部分类的所有视频
        if classification_id == 0:
            # 添加类别筛选条件
            condition['classification_id__in'] = classification_id_list

        # 如果类别不为0
        else:
            # 如果当前类别id在变化后的类别id列表中
            if classification_id in classification_id_list:
                # 选中当前的类别id
                condition['classification_id'] = classification_id

            # 如果当前类别id不在变化后的类别id列表中
            else:
                # 给类别id赋值为0,即选中全部
                kwargs['classification_id'] = 0
                # 添加类别筛选条件
                condition['classification_id__in'] = classification_id_list

    # 获取所有的级别对象
    level_list = models.Level.objects.all()
    # 如果级别id为0,则不进行级别筛选,显示所有级别的视频
    if level_id == 0:
        pass
    # 如果级别id不为0,则进行级别筛选,显示该级别的视频
    else:
        # 添加级别筛选条件
        condition['level_id'] = level_id

    # 按照上述所有的筛选条件进行视频筛选
    video_list = models.Video.objects.filter(**condition)

 
    # models.Video.objects.filter()
    return render(request, 'video2.html', {
        'direction_list': direction_list,
        'class_list': class_list,
        'level_list': level_list,
        'video_list': video_list,
        'kwargs': kwargs,
    })

HTML

{% include 'base.html' %}
    <style>
        .condition a{
            display: inline-block;
            padding: 5px 8px;
            border: 1px solid #dddddd;
        }

        .condition a.active{
            background-color: coral;
            color: white;
        }
    </style>

<body>
    <div class="condition">
        <h1>筛选条件</h1>
{#筛选条件  -   方向#}
        <div>
            {% if kwargs.direction_id == 0 %}
                <a href="{% url 'video2' direction_id=0 classification_id=kwargs.classification_id level_id=kwargs.level_id %}" class="active">全部</a>
            {% else %}
                <a href="{% url 'video2' 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 'video2' direction_id=item.id classification_id=kwargs.classification_id level_id=kwargs.level_id %}" class="active">{{ item.name }}</a>
                {% else %}
                    <a href="{% url 'video2' 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="{% url 'video2' direction_id=kwargs.direction_id classification_id=0 level_id=kwargs.level_id %}" class="active">全部</a>
            {% else %}
                <a href="{% url 'video2' direction_id=kwargs.direction_id classification_id=0 level_id=kwargs.level_id %}" >全部</a>
            {% endif %}

            {% for item in class_list %}
                {% if item.id == kwargs.classification_id %}
                    <a href="{% url 'video2' direction_id=kwargs.direction_id classification_id=item.id level_id=kwargs.level_id %}" class="active">{{ item.name }}</a>
                {% else %}
                    <a href="{% url 'video2' direction_id=kwargs.direction_id classification_id=item.id level_id=kwargs.level_id %}">{{ item.name }}</a>
                {% endif %}

            {% endfor %}

        </div>
{#筛选条件  -   难度级别#}
        <div>
            {% if kwargs.level_id == 0 %}
                <a href="{% url 'video2' direction_id=kwargs.direction_id classification_id=kwargs.classification_id level_id=0 %}" class="active">全部</a>
            {% else %}
                <a href="{% url 'video2' direction_id=kwargs.direction_id classification_id=kwargs.classification_id level_id=0 %}" >全部</a>
            {% endif %}

            {% for item in level_list %}
                {% if item.id == kwargs.level_id %}
                    <a href="{% url 'video2' direction_id=kwargs.direction_id classification_id=kwargs.classification_id level_id=item.id %}" class="active">{{ item.title }}</a>
                {% else %}
                    <a href="{% url 'video2' direction_id=kwargs.direction_id classification_id=kwargs.classification_id level_id=item.id %}">{{ item.title }}</a>
                {% endif %}

            {% endfor %}

        </div>

    </div>
    <div>
        <h1>筛选结果</h1>
        {% for video in video_list %}
            <div>{{ video.title }}</div>
        {% endfor %}

    </div>
</body>