简体   繁体   English

在 django 模板中访问由 object 键入的字典

[英]Accessing dictionary keyed by object in django template

I am trying to access dict values in my django template.我正在尝试访问 django 模板中的 dict 值。 The dict keys are objects. dict 键是对象。 Here is a snippet of my codebase:这是我的代码库的片段:

models.py模型.py

class ProductCategory(models.Mode):
    name = models.CharField(max_length=64, blank=False, null=False, unique=True)
    slug = models.SlugField(blank=False, null=False, unique=True)

class Product(models.Model):
    category = models.ForeignKey(ProductCategory, on_delete = models.CASCADE)

    # other fields
    pass

    def __str__(self):
        return self.title

views.py视图.py

def index(request):
    products = Product.objects.all()
    categorized_products = {}

    for p in products:
        prod_category = p.category
        temp = categorized_products.get(prod_category,[])
        temp.append(p)
        categorized_products[prod_category] = temp

    context = {'products_dict': categorized_products, 'categories': categorized_products.keys() }

    return render(request,'product/index.html', context=context)

mytemplate.html (relevant snippet) mytemplate.html(相关片段)

            <div class="tab-content">
                {% for category in categories %}
                {% if not forloop.counter0 %}
                <div class="tab-pane fade in active" id="{{ category.slug }}">  
                {% else %}                  
                <div class="tab-pane fade in" id="{{ category.slug }}">
                {% endif %}
                    <div >
                        <h4>{{ category.description }}</h4>
                        <div class="container-fluid"> 
                            <div class="row">                                                                  
                                <div class="col-md-3"  style="border:1px solid red;">
                                {% for product in products_dict.category %}
                                    {{ product }}
                                {% endfor %}

When I step through the code with a debugger, I can see that the variable products_dict is a dict and correctly populated by the view.当我使用调试器单步执行代码时,我可以看到变量products_dict是一个字典,并且由视图正确填充。 However, when I run the code, the for loop code is not executed.但是,当我运行代码时,不会执行for loop代码。

Similarly, when I run the same code I have in views.py in the shell, the dict is correctly populated, so I know that there is data in the database and that the retrieved data is being correctly passed to the django template.同样,当我在 shell 中的 views.py 中运行相同的代码时,dict 已正确填充,因此我知道数据库中有数据并且检索到的数据已正确传递给 django 模板。

So why am I unable to access the dict value in the template and why is the product not displaying in my template?那么为什么我无法访问模板中的 dict 值,为什么产品没有显示在我的模板中?

The simple answer is that Django templates don't do that.简单的答案是 Django 模板不会这样做。 Dot reference in template variables does dictionary lookup (among other things) but not based on the value of another variable name:模板变量中的点引用进行字典查找(除其他外)但不基于另一个变量名称的值:

Note that “bar” in a template expression like {{ foo.bar }} will be interpreted as a literal string and not using the value of the variable “bar”, if one exists in the template context.请注意,像 {{ foo.bar }} 这样的模板表达式中的“bar”将被解释为文字字符串,并且不使用变量“bar”的值(如果模板上下文中存在)。

https://docs.djangoproject.com/en/3.0/ref/templates/language/#variables https://docs.djangoproject.com/en/3.0/ref/templates/language/#variables

Generally I would solve this by arranging for something iterable to exist on the category values directly, rather than trying to use the category object as a dict key.通常我会通过安排一些可迭代的东西直接存在于category值上来解决这个问题,而不是尝试使用类别对象作为字典键。 That could be a reverse FK manager:那可能是一个反向 FK 经理:

{% for product in category.products_set.all %}

Or something I set on the in-memory category objects in the view, if I need to transform or filter the products per-category:或者我在视图中的内存类别对象上设置的内容,如果我需要按类别转换或过滤产品:

categories = ProductCategory.objects.all()
for category in categories:
    category.products = [transform_product_somehow(product) for product in category.products_set.all()]

(Optionally with use of fetch_related to prefetch the category products rather than doing an additional query per category.) (可选地使用fetch_related来预取类别产品,而不是对每个类别进行额外的查询。)

You can use a custom filter for that.您可以为此使用自定义过滤器。 In custom_tags.py:在 custom_tags.py 中:

from django import template

register = template.Library()

@register.filter
def get_obj_field(obj, key):
    return obj[key]

Then load the tags in django:然后加载django中的标签:

{% load custom_tags %}

And use it like this:并像这样使用它:

{% for product in products_dict|get_obj_field:category %}
   {{ product }}
{% endfor %}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM