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})
    复制代码
     
     
     
    好文要顶 关注我 收藏该文  
  • 相关阅读:
    字符串替换
    字符串查找
    字符串比较
    字节与字符串相互转换
    1365. How Many Numbers Are Smaller Than the Current Number
    1486. XOR Operation in an Array
    1431. Kids With the Greatest Number of Candies
    1470. Shuffle the Array
    1480. Running Sum of 1d Array
    【STM32H7教程】第56章 STM32H7的DMA2D应用之刷色块,位图和Alpha混合
  • 原文地址:https://www.cnblogs.com/zknublx/p/5937823.html
Copyright © 2011-2022 走看看