在Django模板标签库中导入外部库时出错

3 投票
2 回答
4554 浏览
提问于 2025-04-15 13:10

我正在尝试写一个可以重复使用的Django应用,目的是在你的页面上显示Twitter动态。我知道这个功能已经有很多现成的解决方案了,不过我只是想做个学术练习。:)

目录结构非常简单:

myproject
|__  __init__.py
|__  manage.py
|__  settings.py
|__  myapp
     |__  __init__.py
     |__  admin.py
     |__  conf
          |__  __init__.py
          |__  appsettings.py
     |__  feedparser.py
     |__  models.py
     |__  templates
          |__  __init__.py
     |__  templatetags
          |__  __init__.py
          |__  twitterfeed.py
     |__  views.py
|__  templates
          |__  base.html
|__  urls.py

在运行Django的命令行工具时,twitterfeed.py里定义的函数都能正常工作。我也相信我的模板标签命名和注册都没问题。

如你所见,我使用了非常棒的Universal Feed Parser。我的问题不在于UFP本身,而是在导入模板标签库时无法调用UFP。当我在base.py里使用{% load twitterfeed %}时,出现了以下错误:

'twitterfeed' 不是一个有效的标签库:无法从 django.templatetags.twitterfeed 加载模板库,找不到名为 feedparser 的模块

我用以下语句导入了feedparser:

import re, datetime, time, myapp.feedparser

根据我的理解,这个错误信息有点误导。我觉得在加载模板库时发生了一个导入错误,而这是Django对这个错误的解释。

有没有办法让我在这个可重复使用的应用中导入feedparser.py,而不需要使用这个应用的用户在他们的Python路径中放置feedparser呢?

谢谢!

2 个回答

5

我解决这类问题(也就是把一些库放进我的项目里,让它们能被使用)的方法是这样的。首先,我在项目的根目录下创建一个“ext”文件夹(在你的情况下,就是 myproject/ext)。然后,我把像 feedparser 这样的依赖库放到这个 ext 文件夹里,路径就是 myproject/ext/feedparser

最后,我会修改我的 manage.py 脚本,把 ext/ 文件夹加到 sys.path 的最前面。这意味着无论是运行 ./manage.py runserver 还是 ./manage.py shell,都会找到正确的路径:

# manage.py
import os, sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'ext'))
# ... rest of manage.py

我发现这样做非常有效,特别是当你不想去搞虚拟环境的时候。在你部署项目的时候,也要确保路径是正确的。我通常通过在我的 mod_wsgi app.wsgi 文件开头加上同样的 sys.path.insert 这一行来解决这个问题。

2

这看起来像是那种让人烦恼的相对路径问题。在Python 2.6及更高版本中,这个问题已经解决了(你可以用 import ..feedparser 之类的方式),但在旧版本中通常会有点棘手。一个简单又有效的解决办法就是把 feedparser.py 文件移动到你的 templatetags 目录里,和 twitterfeed.py 放在同一级别。

撰写回答