我想覆盖django admin change_list页面,但我无法找到如何获取实际对象,以便我可以访问object.name
在模板中他们有这段代码
<tr >{% for item in result %}{{ item }}{% endfor %}</tr>
我可以使用的实际对象在哪里
编辑:
看起来result
是行,而item是列。我想要像result.pk
如果结果
,则产生列表https://github.com/django/django/blob/master/django/contrib/admin/templatetags/admin_list.py#L175
答案 0 :(得分:13)
馈送到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.html
模板还会显示cl
上下文变量。
当Django模板在您的示例中迭代result
时,result
是一个ResultList
对象,其中包含预呈现的html,正在呈现的基础对象无法使用
要覆盖此级别的模板,您可能需要实现自己的result_list
类型模板标记,该标记可以返回结果列表,其中基础对象作为属性附加到每个结果。
简而言之,您可能需要:
result_list
模板标记。让它返回results
上下文作为ResultList
预呈现html的列表,让它返回results
包含能够呈现为html的对象,以及每个项目附加的原始基础对象供以后在模板中使用。change_list.html
模板以使用新标记而不是Django的result_list
模板标记。change_list_results.html
模板,以利用模板标记中提供的额外信息,例如每个基础对象的存在。正如您可能已经收集的那样,管理员应用程序通过图层紧密集成。更改其操作非常重要,需要在源的多个部分进行更改和覆盖。
答案 1 :(得分:0)
您还可以使用“ 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 %}
缺点是您可能会在此处使用某些功能(例如排序)。