zoukankan      html  css  js  c++  java
  • Django实现瀑布流,组合搜索

    Django中组合搜索功能

    需求分析

    很多电商网站中有组合搜索的功能,所谓组合搜索就是网页中组合多个条件,对数据库中进行查询,并且将结果显示在页面中,看个例子吧:

    注意红框中的标识,我们可以根据URL来做组合搜索.

    video-3-1-1.html 使用split可以将三个数字取到,
    第一位数字:  分类
    第二位数字:  课程名称
    第三位数字:  级别

    urls.py

    首先,如果想把url按我们的需求取出来,我们可以在urls.py中设置:

    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        # url(r'^student/', views.student),
        url(r'^video-(?P<direction_id>d+)-(?P<classfication_id>d+)-(?P<level_id>d+).html', views.video),
    ]
    URL

    说明下,这里是本身的正则表达式的语法,先分组,并且赋予了变量

    1.此处的(?P<name>…),和普通的(?…):
    
    基本类似。区别在于,此处由于是给此group命名了,所以,后续(同一正则表达式内和搜索后得到的Match对象中),都可以通过此group的名字而去引用此group。
    
    2. group的名字,当前需要是正常的Python标识符,即字母,数字,下划线等,即,没有特殊的字符。
    
    3.同一正则表达式内,每个group的组名,是唯一的,不能重复。
    
    4. 虽然此处group内命名了,但是其仍然和普通的

    modles.py

    from django.db import models
    
    # 技术方向,
    class Direction(models.Model):
        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
    
    
    # 技术分类、语言
    class Classification(models.Model):
        name = models.CharField(verbose_name='名称', max_length=32)
    
        class Meta:
            db_table = 'Classification'
            verbose_name_plural = u'分类(视频分类)'
    
        def __str__(self):
            return self.name
    
    
    # 技术视频,
    class Video(models.Model):
        level_choice = (
            (1, u'初级'),
            (2, u'中级'),
            (3, u'高级'),
        )
        level = models.IntegerField(verbose_name='级别', choices=level_choice, default=1)
    
        classification = models.ForeignKey('Classification', null=True, blank=True)
    
        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
    models

    技术方向:多对多技术分类

    技术视频:一对多技术分类

     views.py

    from django.shortcuts import render
    from app01 import models
    # Create your views here.
    
    def video(request,**kwargs):
        #在url.py中已经设置,结果为:{'direction_id': '3', 'classfication_id': '4', 'level_id': '1'}
        print(kwargs)
        print(request.path_info)
        #request.path._info可以得到url的后缀,比如:/video-3-4-1.html
        current_url = request.path_info
        direction_id = kwargs.get('direction_id','0')
        classfication_id = kwargs.get('classfication_id', '0')
        q = {}
        # 方向是0,表示是全部
        if direction_id == '0':
            #如果技术分类id为0,取分类数据库中的数据,为字典模式,元素为id和name
            cList = models.Classification.objects.values('id', 'name')
            # 分类是0
            if classfication_id == '0':
                # 如果课程也是全部,video-0-0
                pass
            else:
                # video-0-1
                # 否则,选中了对应的分类
                q['classification__id'] = classfication_id
        else:
            #如果分类不是全部,得到分类对应的数据,通过map函数处理迭代器temp,并将其转化为列表,取得ID
            obj = models.Direction.objects.get(id=direction_id)
            temp = obj.classification.all().values('id','name')
            id_list = list(map(lambda x:x['id'],temp))
            cList = obj.classification.all().values('id','name')
    
            if classfication_id == '0':
                # video-1-0
                # 根据方向ID,找到所属的分类ID
    
                print(id_list)
                q['classification__id__in'] = id_list
            else:
                # video-1-1
                #如果分类ID在方向ID列表中
                if int(classfication_id) in id_list:
                    q['classification__id'] = classfication_id
                else:
                    q['classification__id__in'] = id_list
                    #url分割取分类的ID,然后改为0,修改url
                    url_list = current_url.split('-')
                    url_list[2] = "0"
                    current_url = '-'.join(url_list)
        level_id = kwargs.get('level_id',None)
        if level_id != '0':
            q['level'] = level_id
    
        result = models.Video.objects.filter(**q)
    
        dList = models.Direction.objects.values('id', 'name')
    
        lList = models.Video.level_choice
        # level_choice = (
        #     (1, u'初级'),
        #     (2, u'中级'),
        #     (3, u'高级'),
        # )
        return render(request, 'video.html', {"dList":dList,
                                                'cList': cList,
                                                'lList': lList,
                                              'current_url': current_url})
    view

    自定义扩展template函数

    由于处理函数比较复杂,所以我们要写一些自定义的simple_tag函数,用来对相应的a标签进行href预处理,得到相应的url路径,vied_tag.py:

    from django import template
    from django.utils.safestring import mark_safe
    
    ############################################
    #此部分无用
    register = template.Library()
    @register.simple_tag
    def action1(current_url, nid):
        # /video-2-1-3.html
        url_list = current_url.split('-')
        url_list[1] = str(nid)
    
        return '-'.join(url_list)
    
    @register.simple_tag
    def action2(current_url, nid):
        # /video-2-1-3.html
        url_list = current_url.split('-')
        url_list[2] = str(nid)
    
        return '-'.join(url_list)
    
    @register.simple_tag
    def action3(current_url, nid):
        # /video-2-1-3.html
        url_list = current_url.split('-')
        url_list[3] = str(nid) + '.html'
    
        return '-'.join(url_list)
        
    ###################################################
    
    @register.simple_tag
    def ac1(current_url, nid, name):
        # # /video-2-1-3.html
        url_list = current_url.split('-')
        old = url_list[1]
        if old == str(nid):
            temp = '<a class="active" href="%s">%s</a>'
        else:
            temp = '<a href="%s">%s</a>'
    
        url_list[1] = str(nid)
        tag = temp %('-'.join(url_list),name)
    
        return mark_safe(tag)
    
    
    @register.simple_tag
    def ac2(current_url, nid, name):
        # # /video-2-1-3.html
        url_list = current_url.split('-')
        old = url_list[2]
        if old == str(nid):
            temp = '<a class="active" href="%s">%s</a>'
        else:
            temp = '<a href="%s">%s</a>'
    
        url_list[2] = str(nid)
        tag = temp %('-'.join(url_list),name)
    
        return mark_safe(tag)
    
    
    @register.simple_tag
    def ac3(current_url, nid, name):
        # # /video-2-1-3.html
        url_list = current_url.split('-')
        old = url_list[3]
        if old == str(nid) + '.html':
            temp = '<a class="active" href="%s">%s</a>'
        else:
            temp = '<a href="%s">%s</a>'
    
        url_list[3] = str(nid) +  '.html'
        tag = temp %('-'.join(url_list),name)
    
        return mark_safe(tag)
    
    @register.simple_tag
    def all_menu(current_url):
        # video-0-10-0.html
        url_list = current_url.split('-')
        if url_list[1] == '0':
            temp = '<a class="active" href="%s">全部</a>'
        else:
            temp = '<a  href="%s">全部</a>'
    
        url_list[1] = '0'
        temp = temp %('-'.join(url_list))
    
        return mark_safe(temp)
    template

    vedio.html

    {% load vied_tag%}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
                // 设定之间的间隔
            .condition a{
                display: inline-block;
                padding: 5px;
            }
            // 设定当前选择条件的css样式
            .condition a.active{
                background-color: coral;
                color: white;
            }
        </style>
    </head>
    <body>
        <div class="condition">
            <div>
                // 处理全部
                {% all_menu current_url %} :
                // 遍历方向列表
                {% for i in dList %}
                        // 将方向列表中的id,name作为参数传入定义好的自定义函数中处理,生成
                    {% ac1 current_url i.id i.name %}
                {% endfor %}
            </div>
            <div>
                {% for i in cList %}
                    {% ac2 current_url i.id i.name %}
                {% endfor %}
            </div>
            <div>
                {% for i in lList %}
                    {% ac3 current_url i.0 i.1 %}
    
                {% endfor %}
            </div>
        </div>
    
    </body>
    </html>
    View Code

    django实现图片瀑布流布局

    我们在一些图片网站上经常会看到,满屏都是图片,而且图片都大小不一,却可以按空间排列。默认一个div是占用一行,当想把div里的图片并排显示的时候,只能使用float属性,但是,如果两张图片大小不一,那么第二行图片会以第一张最大的图片占用的空间为基准,进行第二行显示,这样的图片布局就非常难看,今天实现的就是瀑布流的形式

    实现效果:

    一般我们做图片布局的时候,都是采用div中加入img,然后将div float起来,这样图片就会并排显示。实现瀑布流的原理就是,我们换一种布局方式,首先定义好需要显示多少列图片,多少列就是多少和div,然后在每列的div中去加入div包着的图片,由于图片外的div是行标签,所以默认独占一行,所以,在本列的div中,图片就无缝的向下排列了,同理,其他列也是,这样总体布局就出现了,看下图

    view.py

    def student(request):
        img_list = [
            {'src': '1.jpg', 'title': 'asdfasdfasdf','content': 'asdf'},# 1
            {'src': '2.jpg', 'title': 'asdfasdfasdf','content': 'asdf'},# 2
            {'src': '3.jpg', 'title': 'asdfasdfasdf','content': 'asdf'},
            {'src': '4.jpg', 'title': 'asdfasdfasdf','content': 'asdf'},
            {'src': '5.jpg', 'title': 'asdfasdfasdf','content': 'asdf'},# 5
            {'src': '6.jpg', 'title': 'asdfasdfasdf','content': 'asdf'},
        ]
    
        return render(request, 'student.html', {"img_list":img_list})
    View Code

    首先分析,现在以四列布局 div分别是a、b、c、d, 那么图片1就在div a中,图片2就在div b中,图片3就在div c中,图片4就在div d中,到图片5时,就继续从div a中开始,后面依次。发现,其中的规律就是第多少张图片 n 除以 4,的余数m 就是第m个div。根据这个规律,我们可以使用模版语言中自定义的方法去进行判断,如果本图片 除以4,正好等于所比较的div 号,那么就放进去

    代码:

    templatetags-vied_tag

    from django import template
    register = template.Library()
    
    @register.filter
    def detail1(value,arg):
    
        """
        查看余数是否等于remainder arg="1,2"
        :param counter:
        :param allcount:
        :param remainder:
        :return:
        """
        allcount, remainder = arg.split(',')
        allcount = int(allcount)
        remainder = int(remainder)
        if value%allcount == remainder:
            return True
        return False
    View Code

    html 代码

    {% load  vied_tag %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .container{
                width: 980px;
                margin: 0 auto;
            }
            .container .column{
                float: left;
                width: 245px;
            }
            .container .item img{
                width: 245px;
            }
        </style>
    </head>
    <body>
    
        <div class="container">
            <div class="column">
                {% for i in img_list %}
                    {% if forloop.counter|detail1:"4,1" %}
                        <div class="item">
                            {{ forloop.counter }}
                            <img src="/static/{{ i.src }}">
                        </div>
                    {% endif %}
                {% endfor %}
            </div>
            <div class="column">
                {% for i in img_list %}
                    {% if forloop.counter|detail1:"4,2" %}
                        <div class="item">
                            {{ forloop.counter }}
                            <img src="/static/{{ i.src }}">
                        </div>
                    {% endif %}
                {% endfor %}
            </div>
            <div class="column">
                {% for i in img_list %}
                    {% if forloop.counter|detail1:"4,3" %}
                        <div class="item">
                            {{ forloop.counter }}
                            <img src="/static/{{ i.src }}">
                        </div>
                    {% endif %}
                {% endfor %}
            </div>
            <div class="column">
                {% for i in img_list %}
                    {% if forloop.counter|detail1:"4,0" %}
                        <div class="item">
                            {{ forloop.counter }}
                            <img src="/static/{{ i.src }}">
                        </div>
                    {% endif %}
                {% endfor %}
            </div>
        </div>
    
    </body>
    </html>
    View Code

    上面只是简单的利用模版语言 实现了瀑布流布局,但是会发现图片列表需要循环四次,这样效率不好,一般情况下,可以使用ajax,先获取到图片列表,然后js去循环列表,然后在循环中,将当前循环的元素索引 去和4相除,拿到余数,最后使用jquery 根据余数进行直接定位到对应的

     参考学习:https://www.cnblogs.com/pycode/articles/django3.html

    
    
  • 相关阅读:
    lr如何获取当前系统时间戳
    linux创建用户、设置密码、修改用户、删除用户
    Linux下安装load generator步骤及问题解决
    怎么将手动设定的IP变成固定的自动IP.
    Redis与Memcached的区别
    memcached 下载安装
    linux上传下载文件rz,sz
    oracle错误码
    sharepoint 2013 附件控件FileUpload怎样检验是否为图片的方法
    10gocm-&gt;session3-&gt;数据备份与恢复
  • 原文地址:https://www.cnblogs.com/lanyinhao/p/9619417.html
Copyright © 2011-2022 走看看