Custom template tag problem: "No module named models"

1,624 views
Skip to first unread message

Chris Amico

unread,
Oct 15, 2008, 2:38:20 AM10/15/08
to Django users
I have a simple bookmarks model based on the one in James Bennett's <a
href="http://code.google.com/p/cab/source/browse/trunk/models.py?
r=130">Cab</a> application. I'm using a generic relation so it can
live in its own app and a user can bookmark any object on the site
(I'm planning on reusing this app on a couple projects). I'm running
into a problem creating an {% if_bookmarked %} template tag.

When I load the tag library I get this error: 'bookmarks' is not a
valid tag library: Could not load template library from
django.templatetags.bookmarks, No module named models

Here's what the tag module looks like:

from django import template
from django.contrib.contenttypes.models import ContentType
from bookmarks.models import Bookmark


class IfBookmarkedNode(template.Node):
def __init__(self, user, obj, nodelist_true, nodelist_false):
self.nodelist_true = nodelist_true
self.nodelist_false = nodelist_false
self.user_id = template.Variable(user_id)
self.obj = template.Variable(obj)

def render(self, context):
try:
self.user_id = template.resolve_variable(self.user_id,
context)
self.obj = template.resolve_variable(self.obj, context)
except template.VariableDoesNotExist:
return ''
ctype = ContentType.objects.get_for_model(obj)
if Bookmark.objects.filter(content_type=ctype,
object_id=obj.id, user__pk=user_id.id):
return self.nodelist_true.render(context)
else:
return self.nodelist_false.render(context)


def do_if_bookmarked(parser, token):
bits = token.contents.split()
if len(bits) != 3:
raise template.TemplateSyntaxError("'%s' tag takes exactly two
arguments" % bits[0])
nodelist_true = parser.parse(('else', 'endif_bookmarked'))
token = parser.next_token()
if token.contents == 'else':
nodelist_false = parser.parse(('endif_bookmarked',))
parser.delete_first_token()
else:
nodelist_false = template.NodeList()
return IfBookmarkedNode(bits[1], bits[2], nodelist_true,
nodelist_false)


And this is the model it should be importing:


class Bookmark(models.Model):
"A bookmarked item, saved by a user with a timestamp"
# generic relation
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type',
'object_id')

# who and when
user = models.ForeignKey(User)
timestamp = models.DateTimeField(auto_now_add=True)



The bookmarking model works fine on its own, and I've gotten the
functions in the template tag to work in isolation in the interpreter,
but when I load the tag library it breaks the template. What am I
missing here?

Daniel Roseman

unread,
Oct 15, 2008, 2:45:44 AM10/15/08
to Django users
On Oct 15, 7:38 am, Chris Amico <eyese...@gmail.com> wrote:
> I have a simple bookmarks model based on the one in James Bennett's <a
> href="http://code.google.com/p/cab/source/browse/trunk/models.py?
> r=130">Cab</a> application. I'm using a generic relation so it can
> live in its own app and a user can bookmark any object on the site
> (I'm planning on reusing this app on a couple projects). I'm running
> into a problem creating an {% if_bookmarked %} template tag.
>
> When I load the tag library I get this error: 'bookmarks' is not a
> valid tag library: Could not load template library from
> django.templatetags.bookmarks, No module named models
>
> Here's what the tag module looks like:
>

<snip>

> The bookmarking model works fine on its own, and I've gotten the
> functions in the template tag to work in isolation in the interpreter,
> but when I load the tag library it breaks the template. What am I
> missing here?

Is the templatetag file itself called bookmarks.py, by any chance? If
so, the code may be trying to import that rather than the top-level
bookmarks directory. Try renaming the file, although I would also
recommend using full paths when importing (ie from
projectname.bookmarks.models).
--
DR

bruno desthuilliers

unread,
Oct 15, 2008, 4:08:01 AM10/15/08
to Django users


On 15 oct, 08:45, Daniel Roseman <roseman.dan...@googlemail.com>
wrote:
(snip otherwise sound advises)

> although I would also
> recommend using full paths when importing (ie from
> projectname.bookmarks.models).

No. *Don't*. If you do so, imports will break when renaming the
<projectname> directory or trying to reuse the bookmark app in another
project.

FWIW, I just don't understand why each an every example in the
Django's manual insists on using this projectname.appname scheme.

Malcolm Tredinnick

unread,
Oct 15, 2008, 4:19:31 AM10/15/08
to django...@googlegroups.com

On Wed, 2008-10-15 at 01:08 -0700, bruno desthuilliers wrote:
[...]

> FWIW, I just don't understand why each an every example in the
> Django's manual insists on using this projectname.appname scheme.

"Insists" is a rather strong word, since nowhere does it say "do this or
else". Also, out of all the code fragments in all the documentation,
very few actually talk about app or project imports at all. So let's
keep things a little bit in perspective. :-)

We take patches to change that kind of stuff if you want to make it
better.

Regards,
Malcolm

Chris Amico

unread,
Oct 15, 2008, 1:17:19 PM10/15/08
to Django users
The templatetag file is indeed called bookmarks.py. I thought of that,
tried renaming it as bookmark_tags.py, and got the same error. I'll
add that the bookmarks app lives on my python path, not in any
particular project, since I'm trying to make this as reusable as
possible.

At one point, I tried just removing the line 'from bookmarks.models
import Bookmark', and the library loaded, but it hit an error
(correctly) when I tried use it, saying Bookmark wasn't defined.


On Oct 14, 11:45 pm, Daniel Roseman <roseman.dan...@googlemail.com>
wrote:
> On Oct 15, 7:38 am, Chris Amico <eyese...@gmail.com> wrote:
>
> > I have a simple bookmarks model based on the one in James Bennett's <a
> > href="http://code.google.com/p/cab/source/browse/trunk/models.py?
> > r=130">Cab</a> application. I'm using a generic relation so it can
> > live in its own app and a user can bookmark any object on the site
> > (I'm planning on reusing this app on a couple projects). I'm running
> > into a problem creating an {% if_bookmarked %}templatetag.
>
> > When I load the tag library I get this error: 'bookmarks' is not a
> > valid tag library: Could not loadtemplatelibrary from
> > django.templatetags.bookmarks,Nomodulenamedmodels
>
> > Here's what the tagmodulelooks like:
>
> <snip>
>
> > The bookmarking model works fine on its own, and I've gotten the
> > functions in thetemplatetag to work in isolation in the interpreter,
> > but when I load the tag library it breaks thetemplate. What am I

RyanP

unread,
Oct 15, 2008, 2:21:18 PM10/15/08
to Django users
Seems like the problem's got to be with the "from bookmarks.models
import Bookmark" line.

The "No module named models" part of your error message suggests that
Django doesn't know about your bookmarks/models.py ... if that app is
on your Pyton path, any chance that it's just not listed in your
INSTALLED_APPS?

Chris Amico

unread,
Oct 15, 2008, 2:40:01 PM10/15/08
to Django users
Wish it were that easy. The app is installed, and it works everywhere
else. If I take out the {% load bookmarks %} from the template, the
rest of the app works fine. I have a view that bookmarks an object,
and it checks if a user has bookmarked that object first.

This is how I did it in the view (part of another app--a database of
online news tools):

def bookmark_tool(request, category_id, tool_id):
"Bookmarks a tool"
user = get_object_or_404(User, pk=request.user.id)
tool = get_object_or_404(Tool,
category__slug__iexact=category_id,
slug__iexact=tool_id)
b_list = [b.content_object for b in user.bookmark_set.all()]
if tool not in b_list:
Bookmark.objects.create(content_object=tool, user=user)
return HttpResponseRedirect(tool.get_absolute_url())

And that works exactly as it should.

felix

unread,
Oct 15, 2008, 9:22:31 PM10/15/08
to Django users

this gets me every time.

the error is yes because the template tag is called bookmarks.py
and its inside a module called bookmarks.py

rename it to bookmarks_tags.py ...

and now ....

DELETE THE DAMNED OLD bookmarks.pyc file !

python is still finding the old compiled file.

its happened to me twice already in the exact same fashion.

-f;lix

Chris Amico

unread,
Oct 15, 2008, 10:53:38 PM10/15/08
to Django users
Tried that. Still no good. I renamed the file as bookmark_tags.py and
deleted every .pyc file in the app. Nothing in my templatetags
directory actually compiled--neither __init__.py nor bookmarks.py
(even after being renamed).

Like I said before, when I take out the import line (from
bookmarks.models import Bookmark) the library loads (even when called
bookmarks.py) and only hits an error when it tries to access
Bookmark.objects.all().

felix

unread,
Oct 16, 2008, 3:56:34 AM10/16/08
to django...@googlegroups.com
oh well.

check that you have an __init__.py file in the templatetags directory

try this:
in bookmark_tags.py  (and do keep the name that way, or later you will be caught by this)

right before the import line throw it in into the debugger:

import pdb; pdb.set_trace()

in the debugger try:

>>> import bookmarks
>>> dir(bookmarks)
>>> bookmarks.__file__

if you can't even import bookmarks then its not actually on your python path.  remember that your python path needs to include the directory directly above the bookmarks app.

f;lix

Chris Amico

unread,
Oct 16, 2008, 5:43:25 PM10/16/08
to Django users
OK, tried all that, got pretty much the same results:

>> import bookmarks
>>> dir(bookmarks)
['__builtins__', '__doc__', '__file__', '__name__', '__path__',
'models']
>>> bookmarks.__file__
'/home/chrisamico/lib/python2.5/bookmarks/__init__.pyc'
>>> from bookmarks import templatetags
>>> dir(templatetags)
['__builtins__', '__doc__', '__file__', '__name__', '__path__']
>>> templatetags.__file__
'/home/chrisamico/lib/python2.5/bookmarks/templatetags/__init__.pyc'
>>> from bookmarks.templatetags import bookmark_tags
> /home/chrisamico/lib/python2.5/bookmarks/templatetags/bookmark_tags.py(4)<module>()
-> from bookmarks.models import Bookmark
(Pdb) from bookmarks.models import Bookmark
*** ImportError: No module named models

Outside the debugger (in python manage.py shell):

>>> from bookmarks.models import Bookmark
>>>

So it's only hitting the import error within bookmark_tags.py. Here's
the directory structure:

*bookmarks
__init__.py
admin.py
models.py
views.py
*templatetags
__init__.py
bookmark_tags.py



On Oct 16, 12:56 am, felix <crucialfe...@gmail.com> wrote:
> oh well.
>
> check that you have an __init__.py file in the templatetags directory
>
> try this:
> in bookmark_tags.py  (and do keep the name that way, or later you will be
> caught by this)
>
> right before the import line throw it in into the debugger:
>
> import pdb; pdb.set_trace()
>
> in the debugger try:
>
> >>> import bookmarks
> >>> dir(bookmarks)
> >>> bookmarks.__file__
>
> if you can't even import bookmarks then its not actually on your python
> path.  remember that your python path needs to include the directory
> directly above the bookmarks app.
>
> f;lix
>

Chris Amico

unread,
Oct 17, 2008, 10:31:16 PM10/17/08
to Django users
I think it's fixed now. After much refreshing (I'm editing in Coda) a
bookmarks.pyc file appeared. Once that was gone, the tag library did
load correctly. I have a different error coming up now, which I'll try
to fix or post separately if I can't.

Thanks for the help and patience, folks.

On Oct 16, 2:43 pm, Chris Amico <eyese...@gmail.com> wrote:
> OK, tried all that, got pretty much the same results:
>
> >> import bookmarks
> >>> dir(bookmarks)
>
> ['__builtins__', '__doc__', '__file__', '__name__', '__path__',
> 'models']>>> bookmarks.__file__
>
> '/home/chrisamico/lib/python2.5/bookmarks/__init__.pyc'>>> from bookmarks import templatetags
> >>> dir(templatetags)
>
> ['__builtins__', '__doc__', '__file__', '__name__', '__path__']>>> templatetags.__file__
>
> '/home/chrisamico/lib/python2.5/bookmarks/templatetags/__init__.pyc'>>> from bookmarks.templatetags import bookmark_tags
> > /home/chrisamico/lib/python2.5/bookmarks/templatetags/bookmark_tags.py(4)<module>()
>
> -> from bookmarks.modelsimport Bookmark
> (Pdb) from bookmarks.modelsimport Bookmark
> *** ImportError:Nomodulenamedmodels
>
> Outside the debugger (in python manage.py shell):
>
> >>> from bookmarks.modelsimport Bookmark
> > > Tried that. Stillnogood. I renamed the file as bookmark_tags.py and
> > > deleted every .pyc file in the app. Nothing in my templatetags
> > > directory actually compiled--neither __init__.py nor bookmarks.py
> > > (even after being renamed).
>
> > > Like I said before, when I take out the import line (from
> > > bookmarks.modelsimport Bookmark) the library loads (even when called
> > > bookmarks.py) and only hits an error when it tries to access
> > > Bookmark.objects.all().
>
> > > On Oct 15, 6:22 pm, felix <crucialfe...@gmail.com> wrote:
> > > > this gets me every time.
>
> > > > the error is yes because thetemplatetag is called bookmarks.py
> > > > and its inside amodulecalled bookmarks.py

Jim D.

unread,
Nov 18, 2008, 2:42:30 PM11/18/08
to Django users
I came across this thread and was having the exact same problem.
*Exactly* the same... I had tried everything you tried to no avail.

I actually fixed it by taking a hint from something that came out of
following along with your debug session in my own code.

I'll put my solution in terms of your code.

This fails:

from django import template
from django.contrib.contenttypes.models import ContentType
from bookmarks.models import Bookmark

This works:

from django import template
from django.contrib.contenttypes.models import ContentType
import bookmarks
from bookmarks.models import Bookmark

I'm not quite sure why though. I wonder, did your solution end up
looking anything like the above?

bruno desthuilliers

unread,
Nov 18, 2008, 5:08:55 PM11/18/08
to Django users


On 15 oct, 09:19, Malcolm Tredinnick <malc...@pointy-stick.com> wrote:
> On Wed, 2008-10-15 at 01:08 -0700, bruno desthuilliers wrote:
>
> [...]
>
> > FWIW, I just don't understand why each an every example in the
> > Django's manual insists on using this projectname.appname scheme.
>
> "Insists" is a rather strong word, since nowhere does it say "do this or
> else".

(just reading this post now - a bit late, but...)

Malcom, I'm not a native English speaker, so I sometimes fail to
convey the exact nuance. Please bear with me !-)

Reply all
Reply to author
Forward
0 new messages