简体   繁体   English

从django模板访问dict / object

[英]accessing dict/object from django template

models.py models.py

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

views.py views.py

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

farms.html farms.html

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

How can i add map_top and map_left to farms objects from views.py ? 如何将views_top和map_left添加到来自views.py的场对象? i've tryied 我试过了

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

but it is not working 但它不起作用

my second aproach was to set in views.py 我的第二个方法是在views.py中设置

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

but i don't know how to access those array from template 但我不知道如何从模板访问这些数组

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

not working 不工作

any ideas ? 有任何想法吗 ? I don't want to store map_top in DB 我不想将map_top存储在DB中

The problem with your first attempt is that slicing a queryset - as you do with farms[0] - always hits the database and gets a fresh instance. 第一次尝试的问题是切片查询集 - 就像使用farms[0] - 总是命中数据库并获得一个新的实例。 That is, the object referred to by farms[0] is not the same one you get when you later iterate through the queryset again. 也就是说, farms[0]引用的对象与稍后再次遍历查询集时获得的对象不同。

The answer is to convert the queryset to a list straight away: then you can set attributes on the instances, and subsequent access will refer to the same instances. 答案是立即将查询集转换为列表:然后您可以在实例上设置属性,后续访问将引用相同的实例。

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

It sounds like you are trying to extend your model to include more information for your template. 听起来您正在尝试扩展模型以包含模板的更多信息。 You can create a data object to represent this. 您可以创建一个数据对象来表示它。 It's a common pattern to create a data class that encapsulates your actual model. 这是创建封装实际模型的数据类的常见模式。 You can even have methods in your data class that you can invoke in the template to do more complicated operations. 您甚至可以在数据类中拥有可以在模板中调用的方法来执行更复杂的操作。

It could be something like 它可能是这样的

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

and in your views.py you can do something like 在你的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 }

And in your template, each farm_data in farm_data_list would have the additional properties defined in your data class. 而在你的模板,每个farm_datafarm_data_list会在你的数据类中定义的附加属性。 An you can use {{ farm_data.some_fn }} in your template to be able to invoke methods on your data class. 您可以在模板中使用{{ farm_data.some_fn }}来调用数据类上的方法。

While you can go down the route of using a custom tag with dictionaries, I prefer using a data class since it's a bit easier to follow down the road when you are revisiting your code. 虽然您可以沿着使用带字典的自定义标记的路线,但我更喜欢使用数据类,因为在您重新访问代码时更容易跟进。

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

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