{% get_related_entries weblog.entry 5 from {{object.categories}} as related_entries %}{% for entry in related_entries %}<p><a href="{{ entry.get_absolute_url }}">{{ entry.title }}</a>{% endfor %}
class RelatedEntryNode(template.Node):def __init__(self, model, number, categories, related_entries):self.model = modelself.number = int(number)self.categories = categoriesself.related_entries = related_entriesdef render(self, context):for cat in self.categories:context[self.related_entries] = self.model._default_manager.filter(categories=cat)[:self.number]return ''
Caught ValueError while rendering: invalid literal for int() with base 10: '{'
../sandbox/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/db/models/fields/related.py in _pk_tracev = getattr(field, prep_func)(lookup_type, v, **kwargs) ...../sandbox/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/db/models/fields/__init__.py in get_prep_lookupreturn self.get_prep_value(value) ...../sandbox/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/db/models/fields/__init__.py in get_prep_valuereturn int(value) ...
I'm trying to create custom templatetags now, while learning Django. When an entry is displayed I want to list other entries with the same categories below the entry. I also wrote a templatetag (following the Practical Django Projects from James Bennet)I'm having problems with using a variable as input in a custom templatetag. The custom templatetag is:{% get_related_entries weblog.entry 5 from {{object.categories}} as related_entries %}{% for entry in related_entries %}<p><a href="{{ entry.get_absolute_url }}">{{ entry.title }}</a>{% endfor %}
<snip>
I'm stuck now at the following error and the debug-information says:
Caught ValueError while rendering: invalid literal for int() with base 10: '{'../sandbox/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/db/models/fields/related.py in _pk_tracev = getattr(field, prep_func)(lookup_type, v, **kwargs) ...../sandbox/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/db/models/fields/__init__.py in get_prep_lookupreturn self.get_prep_value(value) ...../sandbox/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/db/models/fields/__init__.py in get_prep_valuereturn int(value) ...It gets to the filter and gives an UTF error. The Postgres database is UTF8 and I also explicitly added the # -*- coding: utf-8 -*- in the django-file to be sure. I'm using Python 2.6.5 and Django 1.3I think I'm using the wrong approach with regard to the {{object.categories}} in the customtag. What am I doing wrong and how can I solve this?
> {% get_related_entries weblog.entry 5 from object.categories as related_entries %}I found that out already. Now I'm pretty sure the problem is in the rendering. As far as I can tell ( I don't know how to test template tags in a shell ) I get a list of the names of the categories back.
- When I try to iterate the list, I get the 'Caught TypeError while rendering: 'Variable' object is not iterable' error.
- When I don't iterate the variable I get the 'Caught TypeError while rendering: int() argument must be a string or a number, not 'Variable'
- When I try to append queries (with Q or the normal way, because I need an OR relation), that works neither.
??? I don't know how to continue. I'm thinking now of solving this outside Django in a 'normal' python script (somehow) and pass the values as formatted html back to the template. That shouldn't be necessary I think. I'm sure I'm overlooking a very fundamental issue with templates and templatetags, but I just don't get it (yet).
--To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/yYKP0Xoz9XkJ.
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
>It sounds like you're not resolving the variable at all in your render method -->>When you construct the template node, you work with Variable objects, which represent the >context variable as it exists in the template source (eg, html).>>At the point where you actually render your output, you want to resolve that Variable, so >that the template framework actually determines what the contents of that variable should >be, given the current context.>>The example at https://docs.djangoproject.com/en/1.3/howto/custom-template-tags/#passing->template-variables-to-the-tag shows how it should be done. Construct a Variable object in >node.__init__(), and use variable.resolve(context) in node.render()>>IanI already tried that route from the sample and that creates the unicode error. Relevant parts of my code are below.
models.pycategories = models.ManyToManyField('Category', blank=True, null=True, default = None)
{% get_related_entries weblog.entry 5 from object.categories as related_entries %}{% for entry in related_entries %}<p><a href="{{ entry.get_absolute_url }}">{{ entry.title }}</a>{% endfor %}
def __init__(self, model, number, categories, varname):self.categories = template.Variable(categories)
def render(self, context):related = self.varname.resolve(context)return related
Caught AttributeError while rendering: 'unicode' object has no attribute 'resolve'
When I view the entry.categories from the manage shell, it returns a list of categories (I also tried with from object instead of object.categories in the templatetag, but that gave the same error)In [7]: c.categories.all()Out[7]: [<Category: C1>, <Category: C2>, <Category: C3>]Somehow I have to iterate the list of categories (which consist of the name and not the Category.id and retrieve other entries with the same category in the Node render. I have been looking into include-tags too, but I also got iterating errors. I cannot imagine that there isn't an easy solution for these kind of queries. These kind of queries are pretty common to perform, but how ???
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/KsGYSEO2NUkJ.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
>These are my assumptions about the bits of code you've posted:>>models.py>categories = models.ManyToManyField('Category', blank=True, null=True, default = None)>>Assumption: categories is a field defined within a standard Django model; Category is >another model you have defined.
Yes, categories is a field in model Entry
>{% get_related_entries weblog.entry 5 from object.categories as related_entries %}> {% for entry in related_entries %}> <p><a href="{{ entry.get_absolute_url }}">{{ entry.title }}</a>> {% endfor %}>>>Assumption: weblog and object are context variables provided to the template from the view. object is an instance of the model with the categories m2m field you showed above.>>I'm not sure how weblog.entry is relevant.
weblog.entry is the model that is used. The templatetag is used when on a blogentry detail page and should give a list of related entries (with corresponding categories)It comes from django.db.models.get_model()(p117 of Practical Django Projects). That's one of the books I'm learning from and now I'm trying to understand how custom templatetags work. Already made a few and stepping up the complexities
>def __init__(self, model, number, categories, varname):> self.categories = template.Variable(categories)>>Assumption: model, number, categories, and varname are the parameters from the template tag you show in the template snippet above. I am guessing that they are all just the strings, exactly as they >appear in the template.
model = weblog.entrynumber = number of entries to displaycategories = object.categories ; these are the categories linked to the entry (in this case 3 categories: C1, C2 and C3 )varname = related_entries
>>>def render(self, context):> related = self.varname.resolve(context)> return related>>At this point, I presume that you have defined self.varname in __init__ above, as "self.varname = varname", and you have just chosen not to paste that line.>
This was a typo, because I was going back to check your suggestion from the djangoproject example (which I already tried some time before)I corrected this to self.categories.resolve(context) and I didn't get a Template error anymore. But I didn't get any other entries either, and there should be at least 1.
>>Caught AttributeError while rendering: 'unicode' object has no attribute 'resolve'>>First off, self.varname, if I am correct, is just the string "related_entries" here. It doesn't have a "resolve" method, because it's just a string. Variable objects, like self.context, have a "resolve" method.>>If you want to access the categories that you have mentioned in the template, then you can use>self.categories.resolve(context)
See above. My mistake :-(
>>If you want to access "weblog.entry", then you will need to create a Variable from it, like you did with categories:>>def __init__(...):> ...> self.model = template.Variable(model)> ...>>and then resolve it in render(), as self.model.resolve(context)
I'll add the Category as a model. Lowercase just as django.db.models.get_model() needs it.self.modelcat = categoryThe relations are stored in content_entries_categories table in the Database (id, entry.id, category.id). Django retrieves it while rendering the detail_entry template (because it returns the category names in the shell.Basically I want to do the same. Retrieve all entries that have the same category.id as the entry on the detailpage. How can I do that in a templatetag?
>>If you need to push back a value in a variable call related_entries, then you will want to set a value in the context dictionary:>>context[related_entries] = <some value here>>>You won't be able to resolve it as a Variable, because it (presumably) doesn't even exist >before you call your custom tag, but once you set it on the context object, it will be >available to the rest of the template.
This I don't understand. As I understand Django (but correct me if I'm wrong) the related_entries should be a dictionary or list of Entry-instances.
>>Hope this helps,>>Ian>
>>If you need to push back a value in a variable call related_entries, then you will want to set a value in the context dictionary:>>context[related_entries] = <some value here>
>>You won't be able to resolve it as a Variable, because it (presumably) doesn't even exist >before you call your custom tag, but once you set it on the context object, it will be >available to the rest of the template.
>>If you need to push back a value in a variable call related_entries, then you will want to set a value in the context dictionary:>>context[related_entries] = <some value here>Correction on earlier mail when trying some other things. I do this in the def render. This looks like:class RelatedEntryNode(template.Node):def __init__(self, model, number, categories, varname):self.model = modelself.number = int(number)self.categories = template.Variable(categories)self.varname = varname
def render(self, context):related = self.categories.resolve(context)context[self.varname] = relatedreturn ''>>You won't be able to resolve it as a Variable, because it (presumably) doesn't even exist >before you call your custom tag, but once you set it on the context object, it will be >available to the rest of the template.This I don't understand. As I understand Django (but correct me if I'm wrong) the related_entries should be a dictionary or list of Entry-instances.