上次课在详细页面上加了海报。除此之外,数据库里还有其他很多信息我们没有用上,比如演员和导演。这些信息还有个重要的作用,就是把不同的影片关联起来。比如你看了一部电影,对其主演感兴趣,自然就想知道他还演过什么影片。现在,我们就来用演员信息把不同的影片连起来。
仔细看过之前抓取豆瓣影片信息的代码就会发现,豆瓣 API 中是以列表形式提供演员和导演信息。而我在抓取时,将其简化,只是选取了其中的姓名,用逗号(,)拼接起来,作为一个字符串存储在数据库中。因此,如果只是想显示出这些信息,可以简单地实现:
<p>主演:$movie.casts</p>
不过现在我们不仅仅要显示主演的名字,还希望能通过主演关联到其他影片。所以这里需要把这些名字分开,并分别加上超链接。
之前课程中说过,web.py 模板可以让你在 HTML 里写 Python。我们现在就需要在模板里对主演名称的字符串做一些处理:
$ casts = movie.casts.split(',') <p>主演: $for cast in casts: <a href="">$cast</a> </p>
$ 符号开头的代码将会以 Python 的语法执行。需要特别注意的是,$ casts 之间有一个不可缺少的空格,这个空格说明这里是定义了一个新的变量 casts,而不是获取变量 casts 的值。
通过 split 方法将主演名字拆分成一个字符串列表,再通过 for 循环,将其中每一项拿出,加上 a 标签,做成一个超链接。超链接的地址暂时为空,我们还没有能够处理点击演员名的合适页面。
此时刷新页面,可以看到详细页面上已有了演员信息,并且每个名字下面有一个下划线。只是点击之后并不会有特别的反应。
我们是通过在页面模板中处理演员信息,当然你也可以选择另一种方法,即在后台的响应函数,也就是 class movie 的 GET 方法中,将演员信息处理好,作为额外一项参数传递给模板。
那么接下来的问题,点击了演员名称之后要如何处理。我的想法是进行一次搜索,搜索所有影片演员信息中包含此演员名的电影。因为我们的演员信息是一个字符串存储的,所以可以采用之前搜影片名称类似的方法进行。这样会比较省事,但不足之处是,无法区分名字相同或部分相同的情况。而搜索结果的显示,则可以直接复用 index 模板。
首先在 url 里添加跳转规则:
urls = ( '/', 'index', '/movie/(.*)', 'movie', '/cast/(.*)', 'cast', )
然后是处理的方法:
class cast: def GET(self, cast_name): condition = r'casts like "%' + cast_name + r'%"' movies = db.select('movie', where=condition) return render.index(movies)
此处的 GET 方法和 index 里的 POST 方法差不多,唯一不同只是把搜索条件从 title 改为 casts。
最后,再把新增的跳转地址加入到刚刚空着的 a 标签里:
<a href="/cast/$cast">$cast</a>
这里几个名称都用了“cast”,别搞混了。为了区分对于,你也可以分别改为其他名字 cast_name、url_cast、cast_value 等。
这样就已完成演员名的搜索。现在再点击演员名,就可以跳转到搜索结果的页面。
然而,这时候你很可能发现,点击搜索出的结果,并不能再跳转到其他电影的页面(至少我这里是这样)。看了一下,页面被跳转去了
http://127.0.0.1:8080/cast/movie/123456
而不是预想的
http://127.0.0.1:8080/movie/123456
查了代码,原来 问题出在 a 标签的 href 属性上:
"movie/$movie['id']"
前面没有加 /,是表示当前页面下的 movie/xxx 地址,而加了 / 才表示主域名下的 movie/xxx 地址。之前都是从主域名下进行搜索,跳转不会有问题了,而现在一旦使用在 /casts 页面下,跳转就不对了。只要多加上 /,改为
<a href="/movie/$movie['id']">$movie['title']</a>
就没有问题了。
以同样的方式,可以再把导演信息加入搜索功能,这里就不再赘述,各位自行完成。
试着搜了下,发现豆瓣的 top250 里还是比较偏重华语片和老片的。比如张国荣的有 8 部,而克里斯蒂安·贝尔只有 2 部。
code.py
(1.16 KB, 下载次数: 297)
movie.html
(450 Bytes, 下载次数: 188)
|