Django循环并访问模板中的对象和字典项

时间:2023-01-10 20:21:32

So I came across this problem with django templates and I thought the solution might be useful for others:
here I will assume a pretty complicated situation so it also can be used in simpler cases:
let's assume we need to access a list of articles and their id and title in the template. additionally we want to pass some extra data about each article (like publisher) using a dictionary since they are not in the class attributes. what makes it even harder is when you want to access this articles two by two. meaning a for loop iterating over range of 0 to index of last item and being able to access item number i and i+1 at the same time.
this was particularly hard because as you might know if you want to use a dictionary in django template you can't do:

所以我用django模板遇到了这个问题,我认为解决方案可能对其他人有用:在这里我会假设一个相当复杂的情况,所以它也可以在更简单的情况下使用:让我们假设我们需要访问一个文章列表和他们的模板中的ID和标题。另外,我们希望使用字典传递关于每篇文章(如发布者)的一些额外数据,因为它们不在类属性中。更难的是当你想要两个二次访问这篇文章时。意味着for循环在0范围内迭代到最后一项的索引,并且能够同时访问项目编号i和i + 1。这特别难,因为你可能知道如果你想在django模板中使用字典,你不能这样做:

{{ publishers[article.id] }}

because [] are not supported in the template. no big deal you can treat fields as attributes like

因为模板不支持[]。没什么大不了的,你可以将字段视为属性

{{ publishers.0 }}

but django template won't let you do

但是django模板不会让你这样做

{{ publishers.article.id }}

let alone using a for loop and accessing articles through a list and index like :

更不用说使用for循环并通过列表和索引访问文章,如:

{{ publishers.articles.i.id }}

so what do we do???

那么我们该怎么办???

1 个解决方案

#1


0  

so here's the answer. it's a bit over complicated but I wanted to cover all the possibilities.
first off we need to be able to access objects of a dictionary by defining our own filter like this:

所以这就是答案。它有点过于复杂,但我想涵盖所有可能性。首先,我们需要能够通过定义我们自己的过滤器来访问字典的对象,如下所示:

from django import template
register = template.Library()

def hash_dict(h, key):  
   return h[key]

def get_attr(item,field):
   dict_obj = item.__dict__
      return dict_obj[field]

register.filter('hash_dict',hash_dict)
register.filter('get_attr',get_attr)

we'll get to the get_attr method in a moment but for now, we can access dictionary objects in the template :

我们稍后会介绍get_attr方法但是现在,我们可以访问模板中的字典对象:

{% load modulename %}
{{ dictionary|hash_dict:obj.id }}

to have a for loop with counter you can pass a range object or list to the template.

要有一个带计数器的for循环,你可以将范围对象或列表传递给模板。

range_of_article = range(0, len(articles_list), 2)

and somehow pass that variable to the template.
in your template :

并以某种方式将该变量传递给模板。在您的模板中:

{% for i in range_of_article %}
   {% with article=articles|hash_dict:i %}
      {% with article_id=article|get_attr:'id' %}
         {{ publishe|hash_dict:article_id }}

this is where get_attr method comes in handy. I could have just used article.id with no problems here but sometimes that's not the case. I find this workaround to be very useful when you cant access an attrubute of object with object.attribute won't work.
and finally to have access to i and i+1 at the same time:

这是get_attr方法派上用场的地方。我本可以在这里使用article.id没有问题,但有时情况并非如此。当您无法使用object.attribute访问对象的attrubute时,我发现这种解决方法非常有用。最后同时访问i和i + 1:

{% for i in range_of_article %}
   {% with j=i|add:1 %}
      {% with article=articles|hash_dict:i article2=articles|hash_dict:j %}
         {% with article_id=article|get_attr:'id'  article_id2=article2|get_attr:'id'%}
            {{ publishe|hash_dict:article_id }}
            {{ publishe|hash_dict:article_id2 }} 

#1


0  

so here's the answer. it's a bit over complicated but I wanted to cover all the possibilities.
first off we need to be able to access objects of a dictionary by defining our own filter like this:

所以这就是答案。它有点过于复杂,但我想涵盖所有可能性。首先,我们需要能够通过定义我们自己的过滤器来访问字典的对象,如下所示:

from django import template
register = template.Library()

def hash_dict(h, key):  
   return h[key]

def get_attr(item,field):
   dict_obj = item.__dict__
      return dict_obj[field]

register.filter('hash_dict',hash_dict)
register.filter('get_attr',get_attr)

we'll get to the get_attr method in a moment but for now, we can access dictionary objects in the template :

我们稍后会介绍get_attr方法但是现在,我们可以访问模板中的字典对象:

{% load modulename %}
{{ dictionary|hash_dict:obj.id }}

to have a for loop with counter you can pass a range object or list to the template.

要有一个带计数器的for循环,你可以将范围对象或列表传递给模板。

range_of_article = range(0, len(articles_list), 2)

and somehow pass that variable to the template.
in your template :

并以某种方式将该变量传递给模板。在您的模板中:

{% for i in range_of_article %}
   {% with article=articles|hash_dict:i %}
      {% with article_id=article|get_attr:'id' %}
         {{ publishe|hash_dict:article_id }}

this is where get_attr method comes in handy. I could have just used article.id with no problems here but sometimes that's not the case. I find this workaround to be very useful when you cant access an attrubute of object with object.attribute won't work.
and finally to have access to i and i+1 at the same time:

这是get_attr方法派上用场的地方。我本可以在这里使用article.id没有问题,但有时情况并非如此。当您无法使用object.attribute访问对象的attrubute时,我发现这种解决方法非常有用。最后同时访问i和i + 1:

{% for i in range_of_article %}
   {% with j=i|add:1 %}
      {% with article=articles|hash_dict:i article2=articles|hash_dict:j %}
         {% with article_id=article|get_attr:'id'  article_id2=article2|get_attr:'id'%}
            {{ publishe|hash_dict:article_id }}
            {{ publishe|hash_dict:article_id2 }}