美文网首页
2020-05-08--Django项目7--orglist内容

2020-05-08--Django项目7--orglist内容

作者: program_white | 来源:发表于2020-05-09 20:11 被阅读0次

Orglist.html中内容的分页

问题描述:



也就是当列表中数据项很多时,我们不可能把他全部写在一页上,所以要对它进行分页,用户点击那一页的页码,就显示该页的内容。

1.分页组件-----django-pure-pagination

GitHub网址:
https://github.com/jamespacileo/django-pure-pagination

在我们之前也讲过分页操作,使用django自带的分页,但是为了美观,我们要使用这个分页组件。这个组件进行分页时页码不会全部显示,之前的分页会显示全部页码,不好看:


(1)安装组件
pip install django-pure-pagination

我们之前在requirments.txt中已经安装了该组件,所以这里无需下载。(我们每安装一个库或者组件都把它写到requirments.txt中,方便以后的项目部署)


(2)注册组件

在settings.pyz中的INSTALLED_APPS,添加一个:

'pure_pagination'
(3)分页组件的设置

在settings.py中的最后加上:

#分页组件相关的设置
PAGINATION_SETTINGS = {
    'PAGE_RANGE_DISPLAYED': 10,  #主分页部分显示几个
    'MARGIN_PAGES_DISPLAYED': 2,  #省略号前边或后边显示几个
    'SHOW_FIRST_PAGE_WHEN_INVALID': True,  #是否显示第一页
}

2.编写view操作分页

首先我们要分页,就不能在后端服务器中把所有的数据信息传给前台了,要先把数据分成若干部分,再传给前台html。

class OrgView(View):
    def get(self,request,*args,**kwargs):
        '''
        展示授课机构的列表页
        :param request:
        :param args:
        :param kwargs:
        :return:
        '''
        all_orgs = CourseOrg.objects.all()         #查询所有的机构信息
        org_nums = all_orgs.count()          #查询机构的个数
        all_citys = City.objects.all()       #查询所有的城市信息

        #分页部分
        #获取page,如果没找到或者出错都置page为1
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1

        #参数1:作用对象,参数2:单页显示数量,参数3:request
        p = Paginator(all_orgs, per_page=5,request=request)

        orgs = p.page(page)          #获取page页的信息


        return render(request, 'orglist.html',{
            'all_orgs':orgs,
            'org_nums':org_nums,
            'all_citys':all_citys
            })

解析:
(1)首先检测一下错误信息,保证每个page都正常显示.
(2)通过Paginator类实例化,对获取到的全部机构信息进行分割,每页5个
(3)通过Paginator的实例对象(p)中的方法page(页码)获取该页码的内容信息,最后传给模板进行重新进行数据绑定。

3.orglist.html列表信息分页显示的重构

在上一步后台的视图函数把分好的每页的数据信息传给了orglist.html。
当我们运行项目,点击进入到orglist.html时,会出现以下错误:



Page对象不可被迭代。

这是由于在服务器的view中,在没有分页的时候,我们传的是Queryset对象,可以被迭代(在orglist.html中我们使用for循环进行循环显示的),我们现在传值org为Page对象,不能被迭代。
解决:
在orglist.html修改for循环的循环对象:

all_orgs   ----->   all_orgs.objects.list

找到orglidst.html中的页码的html代码:
他是一个无序列表

<div class="pageturn">
                        <ul class="pagelist">
                            <li class="active"><a href="?page=1">1</a></li>
                            <li><a href="?page=2" class="page">2</a></li>
                            <li><a href="?page=3" class="page">3</a></li>
                            <li class="long"><a href="?page=2">下一页</a></li>
                        </ul>
                    </div>

在ul标签下添加:

{{ all_orgs.render }}

把其他的li标签的页码注释了运行后:



但是我们不用这个。哈哈!!
我们使用的时分页组件django-pure-pagination提供的代码。
但是要对它进行改造,改一些变量的名称。

 {% if page_obj.has_previous %}
        <a href="?{{ page_obj.previous_page_number.querystring }}" class="prev">&lsaquo;&lsaquo; {% trans "previous" %}</a>
    {% else %}
        <span class="disabled prev">&lsaquo;&lsaquo; {% trans "previous" %}</span>
    {% endif %}
    {% for page in page_obj.pages %}
        {% if page %}
            {% ifequal page page_obj.number %}
                <span class="current page">{{ page }}</span>
            {% else %}
                <a href="?{{ page.querystring }}" class="page">{{ page }}</a>
            {% endifequal %}
        {% else %}
            ...
        {% endif %}
    {% endfor %}
    {% if page_obj.has_next %}
        <a href="?{{ page_obj.next_page_number.querystring }}" class="next">{% trans "next" %} &rsaquo;&rsaquo;</a>
    {% else %}
        <span class="disabled next">{% trans "next" %} &rsaquo;&rsaquo;</span>
    {% endif %}

我们要把这个组件提供的逻辑代码和orglist原有的页码显示代码进行结合:

<ul class="pagelist">
                            {#   上一页   #}
                            {% if all_orgs.has_previous %}
                                <li class="long"><a href="?{{ all_orgs.previous_page_number.querystring }}"
                                                    class="page">上一页</a></li>
                            {% endif %}
                            {#   页码循环    #}
                            {% for page in all_orgs.pages %}
                                {% if page %}
                                    {% ifequal page all_orgs.number %}
                                        {# 用户点击的是否是当前页码 #}
                                        <li class="active"><a
                                                href="?{{ page.querystring }}">{{ page }}</a>
                                        </li>
                                    {% else %}
                                        <li class="page"><a
                                                href="?{{ page.querystring }}">{{ page }}</a>
                                        </li>
                                    {% endifequal %}
                                {% else %}
                                    <li class="none">...</li>
                                {% endif %}
                            {% endfor %}

                            {#  下一页   #}
                            {% if all_orgs.has_next %}
                                <li class="long"><a href="?{{ all_orgs.next_page_number.querystring }}"
                                                    class="page">下一页</a></li>
                            {% endif %}

                        </ul>

分析:分页的页码list分三部分:

  • 上一页
  • 页码列表
  • 下一页
    1.如果page对象有上一页,那麽就显示列表项--上一页,并且链接到上一页。并加上css样式class=“long”
    2.循环page对象的页码(pages),该页码存在(存在与否与settings中的设置有关),并且是用户点击的页码,那么就显示该循环项{{page}},并加上css样式class=“active”(加黑)。如果不是用户当前页,也显示,但是加上css样式class=“page”(不加黑)。
    页码不存在,那么就显示 ...。
    3.如果page对象有下一页,那麽就显示列表项--下一页,并且链接到下一页。并加上css样式class=“long”
    修改settings中的页码设置:
    主分页只显示3个页码,其他分区显示1个
#分页组件相关的设置
PAGINATION_SETTINGS = {
    'PAGE_RANGE_DISPLAYED': 3,  #主分页部分显示几个
    'MARGIN_PAGES_DISPLAYED': 1,  #省略号前边或后边显示几个
    'SHOW_FIRST_PAGE_WHEN_INVALID': True,  #是否显示第一页
}

orglist一共有6个数据,每页只显示1个
运行效果图:



这些内容及代码在github的分页组件上都有。

机构类别筛选选项内容的实现

当我们访问到orglist.html时,默认显示全部的,在实际开发中,会设置选项进行筛选内容,方便查找。
我们首先找到该部分的html代码:



查看接口为get请求,也就是说当用户点击某一个筛选选项时,其访问服务器的url后会加上该选项的信息。
所以我们要在后端view视图中进行操作获取。
打开apps/organizations/view.py:
我们要把获取筛选信息的逻辑代码写在分页之前,查询数据库数据之后。因为分页是针对于即将要显示与前台的数据,所以用户筛选后的信息也一样要分页。

#筛选选项--类别
        category = request.GET.get('ct','')    #获取前台接口数据
        if category:
            # 过滤类别为用户选择的数据
            all_orgs = all_orgs.filter(category=category)

解析:使用GET方法进行获取前端传过来的数据,如果没有,默认'',如果该字段存在,那么使用ORM进行筛选并再赋给all_orgs,传给前台页面。
运行:



筛选完成。
但是有一个小问题:当我们点击筛选选项时,高亮还是默认全部的选项。
所以我们要在html页面做css样式的判断。
高亮的css:



解决:
首先我们要判断用户点的是哪个按钮,唯一的辨识就是用户点击后传到后台的接口数据--category,所以在后台把该值传过来。

在前台的css,要用做判断依据:

<a href="?city="><span class="{% ifequal category ''%}active2{% endifequal %}">全部</span></a>
<a href="?ct=pxjg&city="><span class="{% ifequal category 'pxjg'%}active2{% endifequal %}">培训机构</span></a>
<a href="?ct=gx&city="><span class="{% ifequal category 'gx'%}active2{% endifequal %}">高校</span></a>
<a href="?ct=gr&city="><span class="{% ifequal category 'gr'%}active2{% endifequal %}">个人</span></a>

把传过来的category在于其点击时传给后台的接口值进行比较,如果相等,那么class=‘active2’显示。形成高亮。默认全部按钮高亮。
运行:
点击‘高校’:


所在地区的筛选选项的实现

1.地区的显示

所在地区的显示相对于机构类别有所不同,他的选项是动态的,要从数据库中循环遍历显示。
那么找到所在地区部分的html代码,对它进行for循环的改造:

<div class="cont">
     <a href="?ct="><span class="active2">全部</span></a>

     {% for city in all_citys %}
          <a href="?city={{ city.id }}&ct="><span class="">{{ city.name }}</span></a>
    {% endfor %}
</div>

但是点击是没有什么效果的。

2.编写地区筛选的视图逻辑

当用户点击了某个地区以后,要显示相应的内容信息,就要对视图进行修改:
在机构类别的筛选逻辑之后,添加以下代码:

 #对所在城市进行筛选
        city_id = request.GET.get('city','')          #获取前台用户点击的选项数据
        if city_id:             #如果存在,
            if city_id.isdigit():          #如果该数据合法,
                 all_orgs = all_orgs.filter(city_id=city_id)         #过滤用户选择的数据

运行:
点击所在地区的选项----沈阳市


数据显示成功。
但是出现了三个问题:

  • 1.机构数量的显示没有变化,一直显示的是所有的机构数量,没有根据相应的选项进行实时更新。
  • 2.当点击机构类别的选项后,再点击所在地区的选项,机构类别的选项重新刷新为全部,也就是说两种筛选选项没有联动起来,都是独立的。
  • 3.高亮的显示没有变换

(1)机构数量实时更新。

首先我们分析,之前我们从后台传递过来的数量一直都是所有的总数,所以我们要改变数量计算的位置,也就是在分页之前,经过两层过滤后的机构总数。

#显示最后绑定到网页上的机构数量。
org_nums = all_orgs.count()

运行:
点击培训机构后:


筛选选项联动

分析:

选项没有联动的原因?
我们查看前端的选项接口:ct和city。机构类别的city没有赋值,所在地区的ct没有赋值。
现在想:当用户点击了机构类别选项后,再点击所在地区选项,要想联动的话,就要把点击机构类别ct的值传给所在地区选项的ct值,用户再点击所在地区的选项时,ct和city都有了值。反之,也是一个道理,先点击地区选项,就要把city.id传给机构类别选项的city,再点击时,也就有了两个值。

解决:
机构类别传给后台的值为category,那么把category从后台传给前台,再绑定到地区的ct值上。
所在地区传给后台的值为city_id,那么把city_id从后台传给前台,但是city_id就是city.id,它本身就是动态的,(根据用户点击的选项不同city.id就不同)
所以把city.id绑定到机构类别的city值上。



也就是互绑。

高亮

相关文章

  • 2020-05-08--Django项目7--orglist内容

    Orglist.html中内容的分页 问题描述: 也就是当列表中数据项很多时,我们不可能把他全部写在一页上,所以要...

  • 项目内容

    代码网址: https://github.com/edx/ease项目网址: https://www.kaggle...

  • 搜索项目内容

    grep -r XX . cd 到文件夹里 可以去搜索内容 记得加后面那个. 今天看到文章,苹果审核后面UIWe...

  • 项目管理内容

    1、项目进度把控(开发时间、测试接入) 2、项目质量把控(代码规范、接口规范、文档规范) 3、项目人力把控 4、项...

  • 项目管理内容

    [1.项目需求整体了解][2.项目人员整体分配][3.项目开发进度把控][4.如何应付客户的需求变动及临时人员及业...

  • 项目章程内容

  • 项目合同内容

    1.当事人各自权利、义务 2.项目费用及工程款的支付方式 1)支付货款条件;2)结算支付的方式;3)拒付款的条件。...

  • 项目章程的内容

    1、项目概述和产品概述 这是一个什么项目?要形成什么样的产品? 2、项目目的和批准项目的理由 为什么做这个项目? ...

  • 项目评估的内容

    1. 项目与企业概况评估 2. 项目建设的必要性评估 3. 项目建设规模评估 4. 资源、配件、燃料以及公...

  • 项目章程的内容

    4.1.3.1 项目章程项目章程是由项目启动者或发起人发布的,正式批准项目成立,并授权项目经理使用组织资源开展项目...

网友评论

      本文标题:2020-05-08--Django项目7--orglist内容

      本文链接:https://www.haomeiwen.com/subject/hyoqnhtx.html