Django:如何在模板中获取命名相关字段

时间:2014-11-30 01:54:41

标签: django

我有一个Django应用程序,主要模型是Bugs。

我有第二个名为Scrub的模型,它有一个指向Bugs模型的FK。

class Scrub(models.Model):
    bug_id = models.ForeignKey(Bugs,related_name='scrublines')
    user = models.ForeignKey(User)
    time = models.DateTimeField()
    field = models.CharField(max_length=50)
    value = models.CharField(max_length=255)

    def __unicode__(self):
        return str(self.bug_id)

从shell中,我可以添加新的Scrub条目。

>>> B = Bugs.objects.get(bug_id=66045)
>>> U = User.objects.get(pk=2)
>>> B.scrublines.create(user=U,time=datetime.datetime.now(),field="field1",value='value1')
<Scrub: 66045>
>>> B.scrublines.create(user=U,time=datetime.datetime.now(),field="field2",value='value2')
<Scrub: 66045>
>>> B.scrublines.create(user=U,time=datetime.datetime.now(),field="field3",value='value3')
<Scrub: 66045>

我可以通过获取所有字段并迭代

来遍历所有字段
>>> lines = B.scrublines.all()
>>> for line in lines:
...   print("%s:%s" % (line.field,line.value))
... 
field1:value1
field2:value2
field3:value3

我想从模板中做的是通过指定字段名称来获取特定的相关行。我可以从shell获得它

>>> B.scrublines.get(field='field1').value
u'value1'

模板遍历所有错误,并将每个字段放入不同的表格单元格中,我想将field1,field2,field3中的值直接添加到单元格中。

{% for bug in bugs %}
<tr class="bugrow" >
    <td>{{bug.bug_id}}</td>

我可以通过在模板中指定字段名称来获取相关的行吗?

2 个答案:

答案 0 :(得分:1)

在Django模板语言中,点表示法可以是字典查找。例如。 {{ foo.bar }}将被视为foo['bar']

使用Python我们可以将其转换为各种函数调用...

class MyGetter(object):

    def __getitem__(self, item):
        return "Trying to get {}".format(item)

def home(req):
    return render(req, "hello.html", {"stuff": MyGetter()})

hello.html中,如果你有这样的话:

<p>{{ stuff.foo }}</p>

您会在页面上看到“试图获取foo”消息。基本上你需要做的就是修改__getitem__的主体以适合你的目的。 (当然,为所有事情提出适当的名称。)

还有其他方法可以做到这一点(例如__getattr__),但我认为使用__getitem__是最明确的。

此外,如果您愿意,也可以 使用自定义模板标签/模板过滤器。全取决于你。我就是这样做的,因为它似乎涉及最少数量的活动部件。

TL; DR

试试这个:

class FieldReader(object):

    def __init__(self, bug):
        self.__bug = bug

    def __getitem__(self, item):
        return self.__bug.scrublines.get(field=item).value

在模板中,您可以使用

{{ field_reader.field1 }}

为您发送给field1构造函数的Bug获取FieldReader的值。

答案 1 :(得分:0)

您可以使用嵌套循环来迭代每个错误的相关清理。

{% for scrub in bug.scrublines.all() %}
    <td>scrub</td>
{% endfor %}

如果您只想打印特定的磨砂区域,请使用scrub.field

**编辑**

由于您的模型,会有很多针对错误的清理。因此,访问它们的正确方法是使用定义的related_name(擦洗线)和all方法