zoukankan      html  css  js  c++  java
  • 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})
    复制代码
     
     
     
    好文要顶 关注我 收藏该文  
  • 相关阅读:
    二分多重匹配(HDU5093)
    2-sat(and,or,xor)poj3678
    某个点到其他点的曼哈顿距离之和最小(HDU4311)
    第k最短路A*启发式搜索
    求树的直径和中心(ZOJ3820)
    并查集hdu4424
    map容器结构体离散化
    二维坐标系极角排序的应用(POJ1696)
    【进阶3-3期】深度广度解析 call 和 apply 原理、使用场景及实现(转)
    判断js数据类型的四种方法,以及各自的优缺点(转)
  • 原文地址:https://www.cnblogs.com/zknublx/p/5937823.html
Copyright © 2011-2022 走看看