如何从django模板中的相关对象获取值

时间:2017-10-04 08:47:36

标签: django django-models django-templates django-views

我对python和django很新,如果主题已经涵盖,我道歉,但我没有找到问题的答案。

我的models.py

中有我们的课程
class Category(models.Model):
    category_type = models.CharField(max_length=50)
    description = models.TextField()

    def __unicode__(self):
        return self.category_type

class Area(models.Model):
    area_type = models.CharField(max_length=50)
    description = models.TextField()

    def __unicode__(self):
        return self.area_type

class Topic(models.Model):
    topic_type = models.CharField(max_length=50)
    description = models.TextField()

    def __unicode__(self):
        return self.topic_type

class Tag(models.Model):
    tag_type = models.CharField(max_length=50)
    description = models.TextField()

    def __unicode__(self):
        return self.tag_type

class GenericRecord(models.Model):
    document_title = models.CharField(max_length=500)
    category = models.ForeignKey("Category")
    area = models.ForeignKey("Area")
    topic = models.ForeignKey("Topic")
    tag = models.ForeignKey("Tag")
    note = models.TextField(null=True, blank=True)
    link = models.TextField(null=True, blank=True)
    file_upload = models.FileField(upload_to='GenericRecord/', null=True, blank=True)

    class Meta:
        abstract = True


class Document(GenericRecord):
    code = models.CharField(max_length=500, null=True, blank=True)
    reference = models.CharField(max_length=500)
    issue_date = models.DateField(auto_now=False, auto_now_add=False)
    validation_date = models.DateField(auto_now=False, auto_now_add=False, null=True, blank=True)

    def get_admin_url(self):
        return reverse("admin:%s_%s_change" % (self._meta.app_label, self._meta.model_name), args=(self.id,))

    def __unicode__(self):
        if self.code:
            return "%s-%s" % (self.code, self.document_title)
        else:
            return "--%s" % self.document_title

这段代码在views.py

def documents_list(request):
    # Generate counts of some of the main objects
    num_docs=Document.objects.all().count()
    docs=Document.objects.all() 
    num_articles=Article.objects.all().count()
    articles=Article.objects.all()
    template='documents_management.html'

    for object in docs:
        object.fields = dict((field.name, field.value_to_string(object)) for field in object._meta.fields)

    # Render the HTML template documents_management.html with the data in the context variable
    return render(request,template,  context={'docs':docs, 'num_docs':num_docs,'docs':docs, 'num_articles':num_articles, 'articles':articles})

在模板中,我试图获取包含所有值的表,但对于相关对象,我得到主键(当然)。

以下是我的模板中的代码:

<table class="w3-table-all">
    {% for object in docs %}
        {%if forloop.first %}

            <tr>
            {% for field, value in object.fields.iteritems %}
                <th>{{ field }}</th>
            {% endfor %}
            </tr>

        {%endif%}
    {% endfor %}

    {% for object in docs %}    
        {% for field, value in object.fields.iteritems %}

             <td>{{ value }}</td>

        {% endfor %}
        </tr>
    {% endfor %}
</table>

What I see in my browser

我的问题是,如何获取对象Category,Area等...以获取category_type,area_type等值?

谢谢!

2 个答案:

答案 0 :(得分:0)

以下是文档中的一个很好的示例:https://docs.djangoproject.com/en/1.11/intro/tutorial03/#use-the-template-system

您要搜索的是question.choice_set.all部分。

由于一些不好的风格而更新

正如daniel所提到的,你应该放弃Field.to_value_string方法。

由于我不是隐式代码的粉丝,我总是建议尽可能明确地编写代码模板,这里是我的模板版本

<table class="w3-table-all">
    {% for doc in docs %}

        {% if forloop.first %}
            <tr>
                <th>Document Title</th>
                <th>Category Type</th>
                <th>Area Type</th>
                <th>...</th>
            </tr>
        {% else %}
            <tr>
                <td>{{ doc.document_title }}</td>
                <td>{{ doc.category.category_type }}</td>
                <td>{{ doc.area.area_type }}</td>
                <td>...</td>
            </tr>
        {% endif %}

    {% endfor %}
</table>

我改变了什么:

  • 只有一个for循环,你开始使用if forloop.first,你也可以使用else case
  • 重构objectdoc,因为对象经常在django中用于模型经理
  • 添加显式doc.area.area_type字段,这样可以防止模型中的新字段出现在模板中,但在此我建议使用隐式编码样式进行显式处理

您也可以从document_list

中删除此内容
for object in docs:
    object.fields = dict((field.name, field.value_to_string(object)) for field in object._meta.fields)

答案 1 :(得分:0)

问题在于您使用ionic cordova platform add ios 。正如该方法的docstring所示,这是用于序列化,而不是用于显示值。

更简单,更有效的方法是使用Field.value_to_string获取实际值;然后,模板将负责将这些转换为字符串,在外键的情况下,将调用相关对象的getattr方法。

__unicode__