Question

So I'm attempting to write a Django reusable app that provides a method for displaying your Twitter feed on your page. I know well that it already exists 20 times. It's an academic exercise. :)

Directory structure is pretty simple:

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

When running the Django shell, the functions defined in twitterfeed.py work perfectly. I also believe that I have the template tags properly named and registered.

As you can see, I use the excellent Universal Feed Parser. My problem is not within UFP itself, but in UFP's inability to be called while importing the template tag library. When I {% load twitterfeed %} in base.py, I get the following error:

'twitterfeed' is not a valid tag library: Could not load template library from django.templatetags.twitterfeed, No module named feedparser

I import feedparser using the following statement:

import re, datetime, time, myapp.feedparser

The best I can tell, this error message is slightly deceiving. I think there's an ImportError going on when the template library is loaded, and this is Django's interpretation of it.

Is there any way I can import feedparser.py within my reusable app without requiring users of the app to place feedparser somewhere in their PythonPath?

Thanks!

Was it helpful?

Solution

This looks like one of those annoying relative path issues - solved in Python 2.6 and higher (where you can do import ..feedparser etc) but often a bit tricky on older versions. One cheap and cheerful way to fix this could be just to move feedparser.py in to your templatetags directory, as a sibling to twitterfeed.py

OTHER TIPS

I solve this kind of problem (shipping libraries that are dependencies for my overall project) in the following way. First, I create an "ext" directory in the root of my project (in your case that would be myproject/ext). Then I place dependencies such as feedparser in that ext directory - myproject/ext/feedparser

Finally, I change my manage.py script to insert the ext/ directory at the front of sys.path. This means both ./manage.py runserver and ./manage.py shell will pick up the correct path:

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

I find this works really well if you don't want to mess around with things like virtualenvs. When you deploy your project you have to make sure the path is correct as well - I usually solve this by adding the same sys.path.insert line to the start of my mod_wsgi app.wsgi file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top