【问题标题】:accessing dict/object from django template从 django 模板访问 dict/object
【发布时间】:2013-10-27 00:25:46
【问题描述】:

models.py

class farm_model(models.Model):
  name=models.CharField(max_length=30)

views.py

def farms(request):
farms=farm_model.objects.all()
context = { 'farms': farms }
return render(request, 'farms.html', context)

农场.html

{% for farm in farms %}
<div style="top: {{ farm.map_top }}px; left: {{ farm.map_left }}px;">{{ farm.name }}</div>

如何将 map_top 和 map_left 添加到 views.py 中的农场对象? 我试过了

farms[0].map_top=80
setattr(farms[0],'map_top',80)

但它不起作用

我的第二种方法是在views.py中设置

farm_web_data={}
farm_web_data[1]={}
farm_web_data[1]['map_top']=80

但我不知道如何从模板访问这些数组

{% for farm in farms %}
<div style="top: {{ farm_web_data.{{ farm.pk }}.map_top }}px;

不工作

有什么想法吗? 我不想将 map_top 存储在数据库中

【问题讨论】:

  • 你是如何计算map_topmap_left的?对于列表中的第二个农场,两者的价值是多少?
  • 这将是固定值。例如,我只为第一个农场设置了 map_top,但在真正的 views.py 和模板中都有所有值
  • 好的,从以农场 ID 为键的视图中准备字典,将其与上下文一起传递并编写 Custom Template Tag 以获取模板中农场的相应值

标签: python django django-models django-templates


【解决方案1】:

听起来您正在尝试扩展模型以包含更多模板信息。您可以创建一个数据对象来表示它。创建封装实际模型的数据类是一种常见模式。您甚至可以在数据类中拥有可以在模板中调用的方法来执行更复杂的操作。

可能是这样的

class FarmData(object):
    def __init__(self, farm, map_top, map_left):
        self.name = farm.name
        self.map_top = map_top
        self.map_left = map_left

    def some_fn(self):
        return some_output

在你的views.py中你可以做类似的事情

farms = farm_model.objects.all()
farm_data_list = []
for farm in farms:
    farm_data = FarmData(farm, map_top, map_left) # I don't know how you are defining map data
    farm_data_list.append(farm_data)

context = { 'farms': farm_data_list }

在您的模板中,farm_data_list 中的每个 farm_data 都将具有在您的数据类中定义的附加属性。您可以在模板中使用{{ farm_data.some_fn }} 来调用数据类上的方法。

虽然您可以在字典中使用自定义标签,但我更喜欢使用数据类,因为在您重新访问代码时更容易遵循。

【讨论】:

  • 您的方式更像是应该以正确的方式完成..但@Daniel 与list(farm_model.objects.all()) 的技巧更简单。无论如何谢谢!
【解决方案2】:

您第一次尝试的问题是切片查询集 - 就像您对 farms[0] 所做的那样 - 总是会访问数据库并获得一个新实例。也就是说,farms[0] 引用的对象与您稍后再次遍历查询集时获得的对象不同。

答案是直接将查询集转换为列表:然后您可以在实例上设置属性,后续访问将引用相同的实例。

farms = list(farm_model.objects.all())
farms[0].map_top = 80

【讨论】:

  • 工作正常!知道如何通过 pk 设置它吗? farms[pk].map_top=80
  • 您可以循环并创建一个字典映射 pk 到对象:mapping = {obj.pk: obj for obj in farms},然后在mapping[pk] 上设置数据(请注意,这将是与列表中的对象相同的对象,所以您仍然可以将列表而不是字典传递给模板)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-18
  • 2011-03-21
  • 1970-01-01
  • 1970-01-01
  • 2013-07-23
  • 1970-01-01
  • 2016-01-16
相关资源
最近更新 更多