4

我想覆盖 django admin change_list 页面,但我无法找到如何获取实际对象,以便我可以访问类似的属性object.name

在模板中,他们有这个代码

<tr >{% for item in result %}{{ item }}{% endfor %}</tr>

我可以使用的实际对象在哪里

编辑:

看起来result是行,项目是列。我想要类似的东西result.pk

如果结果,这会产生列表

https://github.com/django/django/blob/master/django/contrib/admin/templatetags/admin_list.py#L175

4

2 回答 2

17

馈送到的上下文change_list.html包括cl对应于contrib.admin.views.main.ChangeList对象的条目,该对象是包含结果列表的对象。

您可以像这样直接访问结果列表:

{% for object in cl.result_list %}
{{ object.field }}
{% endfor %}

change_list_results.html更改列表结果通过使用result_list模板标签呈现为模板的一部分。渲染模板时,模板还存在上下文变量change_list_results.htmlcl

result当 Django 模板在您的示例中迭代时,result是一个ResultList包含预渲染 html 的对象,正在渲染的底层对象不可用。

要在此级别覆盖模板,您可能需要实现自己的result_list类型模板标记,该标记可以返回结果列表,其中基础对象作为属性附加到每个结果。

简而言之,您可能需要:

  • result_list根据 Django 的实现创建您自己的模板标签。与其将results上下文作为ResultList预呈现的 html 列表返回,不如让它返回results包含能够呈现为 html 的对象,以及每个项目都附有原始基础对象以供以后在模板中使用。
  • 覆盖change_list.html模板以使用您的新标签而不是 Django 的result_list模板标签。
  • 覆盖change_list_results.html模板以利用模板标签中可用的额外信息,例如每个底层对象的存在。

正如您可能已经收集到的那样,管理应用程序通过层非常紧密地集成在一起。更改其操作并非易事,需要在源的多个部分进行更改和覆盖。

于 2013-04-19T04:11:29.737 回答
1

您还可以使用“change_list_template”覆盖您用于管理员的模板,然后扩展 change_list 模板。喜欢

class NoiseFilter200Admin(admin.ModelAdmin):
    change_list_template = 'currencies/nf200_change_list.html'
    list_filter = ['sectors',]
    search_fields = ['name']
    #list_filter = ( MarketCapFilter )

    def market_cap_value(self, obj):
      return obj.market_cap_value > 1000000000

    def changelist_view(self, request, extra_context=None):
        response = super().changelist_view(
            request,
            extra_context=extra_context,
        )
        try:
            qs = response.context_data['cl'].queryset
        except (AttributeError, KeyError):
            return response

        metrics = {
            'total_volume': Sum('volume'),
            'total_mcap': Sum('market_cap'),
        }
        response.context_data['nf_200_list'] = list(
            qs
            .values('rank','ticker','name','priceUSD','market_cap','volume','change_24h')
           # .annotate(**metrics)
            .order_by('-market_cap')[:200]
        )

        response.context_data['nf_200_totals'] = dict(
            qs.aggregate(**metrics)
        )

        return response

然后在你的模板中你像这样遍历结果,你会看到你想要的

{% extends "admin/change_list.html" %}
{% load humanize %}
{% load math_tags %}

{% block content_title %}
    <h1> Noise Filter 200 </h1>
{% endblock %}
{% block result_list %}
<style>
.results table {
    counter-reset: rowNumber;
}

.results tbody tr{
    counter-increment: rowNumber;
}

.results tbody td.rank::before {
    content: counter(rowNumber);;
}
</style>
    <div style="margin: 10px 0;">Total MCap today: {{ nf_200_totals.total_mcap | intword }}, Total volume today: {{ nf_200_totals.total_volume | intword }} </div>
<div class="results">
    <table>
    <thead>
      <tr>
        <th>
          <div class="text">
            Rank
          </div>
        </th>
        <th>
          <div class="text">
            <a href="#">Name</a>
          </div>
        </th>
        <th>
          <div class="text">
            <a href="#">Ticker</a>
          </div>
        </th>
        <th>
          <div class="text">
            <a href="#">PriceUSD</a>
          </div>
        </th>
        <th>
          <div class="text">
            <a href="#">Market cap</a>
          </div>
        </th>
        <th>
          <div class="text">
            <a href="#">Volume</a>
          </div>
        </th>
        <th>
          <div class="text">
            <a href="#">Change 24</a>
          </div>
        </th>
      </tr>
    </thead>
    <tbody>
      {% for row in nf_200_list %}
      <tr class="{% cycle 'row1' 'row2' %}">
        <td class="rank">  </td>
        <td> {{ row.name }} </td>
        <td> {{ row.ticker }} </td>
        <td> $ {{ row.priceUSD|to_string }} </td>
        <td> {{ row.market_cap | intword }} </td>
        <td> {{ row.volume | intword }} </td>
        <td> {{ row.change_24h | percent}} </td>
      </tr>
      {% endfor %}
    </tbody>

  </table>
</div>
{% endblock %}
{% block pagination %}{% endblock %}

缺点是你可以在这里使用一些你得到的功能(比如排序)。

于 2018-08-01T12:47:46.110 回答