Django DetailView 模板显示所有字段的显示值

Posted

技术标签:

【中文标题】Django DetailView 模板显示所有字段的显示值【英文标题】:Django DetailView Template show display values of all fields 【发布时间】:2012-04-19 02:47:08 【问题描述】:

我制作了一个模板来显示模型中的所有字段和值,它看起来像这样:

## detail_template.html ##
% for name, value in object.get_fields %
    <p>
        <label>% trans name %:</label>
        <span> value|default:"Not available" </span>
    </p>
% endfor %

在类中你可以看到声明的get_fields函数:

## models.py ##
Class Object:
    ...many fields...

    def get_fields(self):
        return [(field.verbose_name, field._get_val_from_obj(self)) for field in self.__class__._meta.fields]

问题是,例如,当我有一个带有选项的 CharField 时,例如:

## models.py ##
GENDER_CHOICES = (
    ('M', 'Male'),
    ('F', 'Female'),
)
        ...all other fields ...
    sex =   models.CharField(verbose_name=u"Sex", max_length=1, choices=GENDER_CHOICES)

它显示M或F,我要做的是加载所有字段的get_NAMEFIELD_display而不手动执行所有字段:

<p>
    <label>% trans 'Sex' %:</label>
    <span> object.get_sex_display|default:"Not available" </span>
</p>

我有一个线索:Django Contrib Admin 在列出对象时会这样做,所以我确信有一种通用的方法可以做到这一点,我也感谢任何帮助。

【问题讨论】:

【参考方案1】:

Django >= 2.0

field._get_val_from_obj() 在 Django 2.0 中被删除,改用field.value_from_object()

get_fields() 添加到您的models.py

class Object(Model):
    field1 = CharField(max_length=150)
    field2 = CharField(max_length=150)

    def get_fields(self):
        return [(field.verbose_name, field.value_from_object(self)) for field in self.__class__._meta.fields]

然后在您的template.html 上将其称为object.get_fields

<table>
    % for label, value in object.get_fields %
        <tr>
            <td> label </td>
            <td> value </td>
        </tr>
    % endfor %
</table>

【讨论】:

感谢@JV conseil;对于我的模型有 50 多个字段,它就像一个魅力。但是,我能做些什么与外键相关?我有一个包含所有关系类型的模型,但我没有在外键字段上获得所需的值。例如,使用您的代码,一行显示 sales_agent = 6。我假设该数字是销售代理的 id(它是匹配的)。如何显示销售代理的用户名?(自定义用户模型有一个布尔字段“is_sales_agent”)【参考方案2】:

我认为你应该添加另一个方法:

def get_field_value(self, field):
    try:
        return self._get_FIELD_display(field)
    except something:
        return field._get_val_from_obj(self)

并在你的生成器中使用它。

【讨论】:

我明白了,我试过了。它正在调用所有 get_field_displays,但现在所有其他没有该功能的字段都没有返回 get_val_from_obj =(我需要知道它的异常没有 get_field_display 时给出 运行 Python shell,检索对象并尝试调用 obj._get_FIELD_display('some_non_existent_field') - 你会得到异常 不需要添加其他方法,不会引发异常。如果调用self._get_FIELD_display(field) if即使没有get_field_display方法也返回值=) 我明白了,谢谢。比你可以检查field的类型并根据它选择方法。 我仍然没有为我创建的 get_field_display 方法工作,例如,我有一个字段状态:status = models.IntegerField(verbose_name=u"Status", db_index=True, default=1) 我在模型中放入了方法:def get_status_display(self): if self.status == 1: return "Active" else: return "Inactive" 它继续显示 1 和0.

以上是关于Django DetailView 模板显示所有字段的显示值的主要内容,如果未能解决你的问题,请参考以下文章

Django - 评级模型示例 DetailView 模板

django如何循环通过通用detailview传回的上下文对象?

Django DetailView模板默认字段值不起作用

django DetailView 没有从 ManyToMany 字段中捕获数据

Django:在通用 DetailView 中实现表单

Django 3:将数据添加到 DetailView