自己写一个在线学习网站记录之按照不同的筛选条件筛选符合条件的数据并显示

筛选每个城市的培训机构

在前端界面上按照城市的id来显示城市的信息。

      
      
1
2
3
      
      
{% for city in all_cities %}
<a href="?city={{ city.id }}"><span class="">{{ city.name }}</span></a>
{% endfor %}

在views(视图函数)中我们根据条件进一步筛选。

这里有一个小常识。比如我们在在定义培训机构的model的时候,有一个外键,我们虽然传入的字段名称是city,但是在数据库中实际存储的字段名称是city_id, 这样就给我们使用数据带来极大的方便。

      
      
1
2
3
4
5
      
      
# 取出筛选的城市
city_id = request.GET.get('city', '')
if city_id:
all_orgs = all_orgs.filter(city_id)

这里刚刚出现了报错,说参数错误:

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
      
      
Request Method: GET
Request URL: http://localhost:8000/org_list/?city=1
Django Version: 1.9
Exception Type: ValueError
Exception Value:
not enough values to unpack (expected 2, got 1)
Exception Location: /home/peter/mymooc/mymoocvenv/lib/python3.5/site-packages/django/db/models/sql/query.py in build_filter, line 1146
Python Executable: /home/peter/mymooc/mymoocvenv/bin/python
Python Version: 3.5.2
Python Path:
['/home/peter/mymooc/apps',
'/home/peter/mymooc',
'/root/.venvburrito/lib/python2.7/site-packages',
'/root/.venvburrito/lib/python2.7/site-packages/setuptools-28.8.0-py2.7.egg',
'/root/.venvburrito/lib/python2.7/site-packages/pip-9.0.1-py2.7.egg',
'/home/peter/mymooc/mymoocvenv/lib/python35.zip',
'/home/peter/mymooc/mymoocvenv/lib/python3.5',
'/home/peter/mymooc/mymoocvenv/lib/python3.5/plat-x86_64-linux-gnu',
'/home/peter/mymooc/mymoocvenv/lib/python3.5/lib-dynload',
'/usr/lib/python3.5',
'/usr/lib/python3.5/plat-x86_64-linux-gnu',
'/home/peter/mymooc/mymoocvenv/lib/python3.5/site-packages']

修改如下:

      
      
1
2
      
      
if city_id:
all_orgs = all_orgs.filter(city_id=int(city_id))

ok,因为city_id在数据库中也是以整形数的形式存储的,也就是int类型的。而从前端页面传过来的的city_id是字符串类型的,所以需要强制转换成整形数,才能正确的找到要筛选的数据。

附上filter的源码:

      
      
1
2
3
4
5
6
      
      
def filter(self, *args, **kwargs):
"""
Returns a new QuerySet instance with the args ANDed to the existing
set.
"""
return self._filter_or_exclude(False, *args, **kwargs)

我们继续做选中状态的处理,如果当前的city的id和后端传过来的city的ID一样,那么就把当前的city设置成选中的状态。

这里总结的点就是每一个链接都要有一个合理的值,这个值可以是后台传过来的东西。

      
      
1
2
3
4
5
6
7
8
9
10
11
      
      
<h2>机构类别</h2>
<div class="cont">
<a href="?city={{ city.id }}"><span class="{% ifequal category '' %}active2{% endifequal %}">全部</span></a>
大专栏   自己写一个在线学习网站记录之按照不同的筛选条件筛选符合条件的数据并显示v class="line">
<a href="?ct=trainingorg&city={{ city.id }}"><span class="{% ifequal category 'trainingorg' %}active2{% endifequal %}">培训机构</span></a>
<a href="?ct=university&city={{ city.id }}"><span class="{% ifequal category 'university' %}active2{% endifequal %}">高校</span></a>
<a href="?ct=personal&city={{ city.id }}"><span class="{% ifequal category 'personal' %}active2{% endifequal %}">个人</span></a>
</div>

在这里培训机构的类别是固定的,所以不用再随着后台传入数据的变化而变化。但是培训机构的信息是从后端传过来的。

      
      
1
2
3
4
5
6
      
      
<div class="cont">
<a href="?ct={{ category }}"><span class="{% ifequal city_id '' %} active2 {% endifequal %}">全部</span></a>
{% for city in all_cities %}
<a href="?city={{ city.id }}&ct={{ category }}"><span class="{% ifequal city_id city.id|stringformat:"i" %}active2{% endifequal %}">{{ city.name }}</span></a>
{% endfor %}
</div>

在这里实现双重筛选,所以每次判断的条件都会取交集。


在培训机构的界面有一个机构排名,我们这里默认按照人气排名。其实这也是一个筛选的问题,或者说是一个排序的问题。

人气体现在什么地方呢,这么看是体现在点击量上,因为点击量越多,说明越受关注。具体的实现如下,直接上代码:

      
      
1
      
      
hot_orgs = all_orgs.order_by("click_num")[:5]

首先定义hot_oegs来存储筛选的信息,比如上面的代码的意思就是在所有的培训机构中抽出人气(点击量)前五名的培训机构。all_orgs是一个列表形式的,我们使用python中的内置的order_by函数对里面的元素进行排序,将排序结果做成切片,显示排名在前的前几个。然后

      
      
1
2
3
4
5
6
7
8
9
10
      
      
return render(request, "org-list.html", {
"all_orgs" : all_orgs,
"orgs" : orgs,
"all_cities" : all_cities,
"city_id":city_id,
"category":category,
"org_nums":org_nums,
"hot_orgs":hot_orgs,
"sort":sort,
})

我们将hot_orgs 传到前端文件,并且传入的名称也是hot_orgs,在前端的html文件中:

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
      
      
<div class="right companyrank layout">
<div class="head">授课机构排名</div>
{% for curent_org in hot_orgs %}
<dl class="des">
<dt class="num fl">{{ forloop.counter }}</dt>
<dd>
<a href="/company/2/"><h1>{{ curent_org.name }}</h1></a>
<p>{{ curent_org.address }}</p>
</dd>
</dl>
{% endfor %}
</div>
</div>

这样就完成了机构的排名。

接下来类似,可以实现按照学习人数和课程数进行升序或者降序排序以等等,其实和前面的功能是类似的。


这里还有几个问题要解决下,一个是template中的

      
      
1
      
      
{% ifequal %}{% endifequal %}

接着是表示相等的等号的问题,在views.py文件中,因为是python的语法,所以表示相等的符号是双等号,在templates中(也就是html文件中,表示相等的符号是一个等号),这个要弄清楚。

python自带了很多很有用的函数,这个是它强大的地方。

猜你喜欢

转载自www.cnblogs.com/wangziqiang123/p/11712679.html
今日推荐