django多条件筛选搜索(项目实例)

Posted 朝阳的向日葵

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django多条件筛选搜索(项目实例)相关的知识,希望对你有一定的参考价值。

多条件搜索在很多网站上都有用到,比如京东,淘宝,51cto,等等好多购物教育网站上都有,当然网上也有很多开源的比楼主写的好的多了去了,仅供参考,哈哈

先来一张效果图吧,不然幻想不出来是什么样的,前端样式很low,毕竟主要是说后台的嘛,前端为了简单测试就简单的写出来啦,喜欢好的样式可以自己去调哈

写后台的应该都知道先从数据库方面入手,所以我们先来设计数据库

 

数据库设计

1、视频video

复制代码
class Video(models.Model):

    status_choice = (
        (0, u\'下线\'),
        (1, u\'上线\'),
    )
    level_choice = (
        (1, u\'初级\'),
        (2, u\'中级\'),
        (3, u\'高级\'),
    )
    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=256)

    create_date = models.DateTimeField(auto_now_add=True)

    class Meta:
        db_table = \'Video\'
        verbose_name_plural = u\'视频\'

    def __str__(self):
        return self.title
复制代码

2、视频方向Direction

复制代码
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 = u\'方向(视频方向)\'

    def __str__(self):
        return self.name
复制代码

3、视频分类Classification

复制代码
class Classification(models.Model):
    weight = models.IntegerField(verbose_name=\'权重(按从大到小排列)\', default=0)
    name = models.CharField(verbose_name=\'名称\', max_length=32)

    class Meta:
        db_table = \'Classification\'
        verbose_name_plural = u\'分类(视频分类)\'

    def __str__(self):
        return self.name
复制代码

好了大家一起来分析下数据库设计

  • 视频方向Direction类和视频分类Classification多对多关系,因为一个视频方向可以有多个分类,一个视频分类也可以有多个视频方向视频分类

  • Classification视频分类和视频Video类是一对多关系,因为一个分类肯定有好多视频

  • 视频Video类中level_choice 与视频也是一对多关系,因为这个也就这三个分类,所以我选择把他放在内存里面取,毕竟这玩意常年不会变

 

url映射

复制代码
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r\'^admin/\', admin.site.urls),
    url(r\'^video-(?P<direction_id>\\d+)-(?P<classification_id>\\d+)-(?P<level_id>\\d+).html\', views.video),
]
复制代码

输入的url为:http://127.0.0.1:8080/video-0-0-0.html

  • 中间第一个0代表视频方向,第二个0代表食品分类,第三个0是视频等级,这个是根据汽车之间那个二手车学的,用着很方便哈哈

  • 0代表全部,然后递增,当选择运维自动化,第一个0就会变成1

  • 下面那些都是一样的道理

 

前端代码

前端HTML,有用到django的simple_tag,从总体效果图可以看出,前端主要分为两部分,选择部分和视频展示部分

1、选择部分

复制代码
    <h3>选择:</h3>
    <div>
        {% action_all current_url 1 %} :
        {% for item in direction_list %}

             {% action current_url item %}
        {% endfor %}
    </div>
    <div>
        {% action_all current_url 2 %} :
        {% for item in class_list %}

            {% action current_url item %}
        {% endfor %}
    </div>
    <div>
        {% action_all current_url 3 %} :
        {% for item in level_list %}
            {% action current_url item %}
        {% endfor %}
    </div>
复制代码

中间主要是用simple_tag来做的前端代码

复制代码
@register.simple_tag
def action_all(current_url,index):
    """
    获取当前url,video-1-1-2.html
    :param current_url:
    :param item:
    :return:
    """
    url_part_list = current_url.split(\'-\')
    if index == 3:
        if url_part_list[index] == "0.html":
            temp = "<a href=\'%s\' class=\'active\'>全部</a>"
        else:
            temp = "<a href=\'%s\'>全部</a>"

        url_part_list[index] = "0.html"
    else:
        if url_part_list[index] == "0":
            temp = "<a href=\'%s\' class=\'active\'>全部</a>"
        else:
            temp = "<a href=\'%s\'>全部</a>"

        url_part_list[index] = "0"


    href = \'-\'.join(url_part_list)

    temp = temp % (href,)
    return mark_safe(temp)


@register.simple_tag
def action(current_url, item,index):
    # videos-0-0-1.html
    # item: id name
    # video-   2   -0-0.html
    url_part_list = current_url.split(\'-\')
 
    if index == 3:
        if str(item[\'id\']) == url_part_list[3].split(\'.\')[0]:  #如果当前标签被选中
             temp = "<a href=\'%s\' class=\'active\'>%s</a>"
        else:
            temp = "<a href=\'%s\'>%s</a>"
 
        url_part_list[index] = str(item[\'id\']) + \'.html\' #拼接对应位置的部分url
    else:
        if str(item[\'id\']) == url_part_list[index]:
            temp = "<a href=\'%s\' class=\'active\'>%s</a>"
        else:
            temp = "<a href=\'%s\'>%s</a>"
 
        url_part_list[index] = str(item[\'id\'])
 
    ur_str = \'-\'.join(url_part_list)  #拼接整体url
    temp = temp %(ur_str, item[\'name\']) #生成对应的a标签
    return mark_safe(temp)  #返回安全的html
复制代码

 

2、视频展示区域

复制代码
    <h3>视频:</h3>
    {% for item in video_list %}
        <a class="item" href="{{ item.href }}">
            <img src="/{{ item.img }}" width="300px" height="400px">
            <p>{{ item.title }}</p>
            <p>{{ item.summary }}</p>
        </a>
    {% endfor %}
复制代码

关键来啦关键来啦,最主要的处理部分在这里,往这看,往这看,往这看,主要的事情说三遍哈

视频后台逻辑处理部分

复制代码
def video(request,*args,**kwargs):
    print(kwargs)
    # 当前请求的路径
    request_path = request.path
    # 从数据库获取视频时的filter条件字典
    q = {}
    # 状态为审核通过的
    q[\'status\'] = 1
    # 获取url中的视频分类id
    class_id = int(kwargs.get(\'classification_id\'))
    # 从数据库中获取所有的视频方向(包括视频方向的id和name)
    direction_list = models.Direction.objects.all().values(\'id\',\'name\')

    # 如果视频方向是0
    if kwargs.get(\'direction_id\') == \'0\':
        # 方向选择全部
        # 方向id=0,即获取所有的视频分类(包括视频分类的id和name)
        class_list = models.Classification.objects.all().values(\'id\', \'name\')
        # 如果视频分类id也为0,即全部分类,那就什么都不用做,因为已经全取出来了
        if kwargs.get(\'classification_id\') == \'0\':
            pass
        else:
            # 如果视频分类不是全部,过滤条件为视频分类id在[url中的视频分类id]
            q[\'classification_id__in\'] = [class_id,]

    else:
        print(\'方向不为0\')
        # 方向选择某一个方向,
        # 如果分类是0
        if kwargs.get(\'classification_id\') == \'0\':
            print(\'分类为0\')
            # 获取已选择的视频方向
            obj = models.Direction.objects.get(id=int(kwargs.get(\'direction_id\')))
            # 获取该方向的所有视频分类
            class_list = obj.classification.all().values(\'id\', \'name\')
            # 获取所有视频分类对应的视频分类id
            id_list = list(map(lambda x: x[\'id\'], class_list))
            # 过滤条件为视频分类id in [该方向下的所有视频分类id]
            q[\'classification_id__in\'] = id_list 
        else:
            # 方向不为0,分类也不为0
            obj = models.Direction.objects.get(id=int(kwargs.get(\'direction_id\')))
            class_list = obj.classification.all().values(\'id\', \'name\')
            id_list = list(map(lambda x:x[\'id\'], class_list))
            # 过滤条件为视频分类id in [已经选择的视频分类id]
            q[\'classification_id__in\'] = [class_id,] 
            print(\'分类不为0\')
            # 当前分类如果在获取的所有分类中,则方向下的所有相关分类显示
            # 当前分类如果不在获取的所有分类中,
            if int(kwargs.get(\'classification_id\')) in id_list:
                pass
            else:
                print(\'不再,获取指定方向下的所有分类:选中的回到全部\')
                url_part_list = request_path.split(\'-\')
                url_part_list[2] = \'0\'
                request_path = \'-\'.join(url_part_list)
    # 视频等级id
    level_id = int(kwargs.get(\'level_id\'))
    if level_id == 0:
        pass
    else:
        # 过滤条件增加视频等级
        q[\'level\'] = level_id 

    # 取出相对应的视频
    video_list = models.Video.objects.filter(**q).values(\'title\',\'summary\', \'img\', \'href\')
    # 把视频等级转化为单个标签是字典格式,整体是列表格式
    ret = map(lambda x:{"id": x[0], \'name\': x[1]}, models.Video.level_choice)
    level_list = list(ret)
    return render(request, \'video.html\', {\'direction_list\': direction_list,
                                          \'class_list\': class_list,
                                          \'level_list\': level_list,
                                          \'current_url\': request_path,
                                          "video_list": video_list})
复制代码

 

 
 
 
好文要顶 关注我 收藏该文  

以上是关于django多条件筛选搜索(项目实例)的主要内容,如果未能解决你的问题,请参考以下文章

jquery实现多条件筛选特效代码分享

Django实现组合搜索的方法示例

Django实现组合搜索的方法示例

JS前端数据多条件筛选(商品搜索)

Django实现组合搜索的方法示例

关于web多标签多条件筛选的思考