创建一个按字段名称分组的列表视图和 link 到详细信息 - django admin
Create a list view with group by field name and link to details - django admin
所以我有以下 table:
class IncomeStatementQuarterly(models.Model):
date = models.DateField()
statement = models.CharField(max_length=1000, blank=True, null=True)
ticker = models.CharField(max_length=1000, blank=True, null=True)
security = models.ForeignKey(SecuritiesTable, models.DO_NOTHING)
line_item = models.CharField(max_length=1000, blank=True, null=True)
amount = models.DecimalField(max_digits=65535, decimal_places=4, blank=True, null=True)
class Meta:
ordering=('ticker',)
verbose_name = "Income statement / Quarterly"
verbose_name_plural = "Income statements / Quarterly"
managed = False
db_table = 'income_statement_quarterly'
unique_together = (('date', 'ticker', 'line_item'),)
以及我的 admin.py class 中的以下内容:
@admin.register(IncomeStatementQuarterly)
class IncomeStatementQuarterlyAdmin(admin.ModelAdmin):
date_hierarchy = 'date'
list_filter = ('line_item',)
list_display = ("ticker", "date", "statement", "line_item", 'amount')
search_fields = ['ticker']
list_display_links = ('ticker',)
def has_add_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False
def has_change_permission(self, request, obj=None) -> bool:
return False
我的目标是创建一个按 'ticker' 和 'date' 字段分组的视图。
截至目前,我的管理视图正在显示我模型的每一行
像这样:
我想按代码和日期重新组合所有内容,这样我就会有一个 link 如果单击它,我将拥有基于给定的日期和代码组合的所有行。
这可能吗?
过去 5 天我一直在到处寻找,我正准备开始一个名为 statements_list 的新模型,该模型由我当前模型的字段(代码、日期)的所有独特组合组成这将有一个主键 link 将其与当前模型(日期、代码)字段的唯一组合
我希望这不会太混乱...
基本上最终结果看起来像这样(基于图片上的可用内容):
- 一个 | 2005 年 1 月 31 日 ---> link 所有带有这些参数的语句
- 一个 | 2005 年 4 月 30 日 ---> link 所有带有这些参数的语句
您可以通过覆盖 ModelAdmin class 的 get_queryset() 方法并使用 group_by查询.
queryset = IncomeStatementQuarterly.objects.values('date', 'ticker').annotate(max_id=Max('id'))
In mysql raw query like,
SELECT date, ticker, MAX(id) AS "max_id"
FROM incomestatementquarterly
GROUP BY date, ticker
但是如果您使用 admin default change_list 模板 那么这个查询会给您一个 error。因为 django admin 在模板中渲染值时期望查询集中的 对象列表 和查询集中的 group_by 查询 return 作为 字典列表.
如果你想使用上面的查询,那么你覆盖change_list模板并渲染数据本身。
另一种解法:
另一种获取相同数据的方法,
覆盖 ModelAdmin 的 get_queryset() 方法 class
您的管理员 class ,
@admin.register(IncomeStatementQuarterly)
class IncomeStatementQuarterlyAdmin(admin.ModelAdmin):
list_display = ("ticker", "date", "view_details")
....
....
def get_queryset(self, request):
max_ids_subquery = IncomeStatementQuarterly.objects.values('date', 'ticker').annotate(max_id=Max('id')).values('max_id')
queryset = IncomeStatementQuarterly.objects.filter(id__in=max_ids_subquery)
return queryset
def view_details(self, obj):
date = obj.date
next_date = date + datetime.timedelta(days=1)
url = ("%s?ticker=%s&date__gte=%s&date__lt=%s") % (reverse('admin:your_app_incomestatementquarterlyproxy_changelist'),obj.ticker, date, next_date)
return format_html('<a class="button" href="{}">View</a>',url)
在mysql查询中类似,
SELECT * FROM incomestatementquarterly
WHERE id IN ( SELECT MAX(id) AS "max_id" FROM incomestatementquarterly t1 GROUP BY t1.date, t1.ticker)
您创建了一个代理模型并注册了这个模型,点击查看详细信息您重定向到这个代理模型管理员class,这是确切的 您的模型管理员 class.
class IncomeStatementQuarterlyProxy(IncomeStatementQuarterly):
class Meta:
proxy = True
代理模型管理员class
@admin.register(IncomeStatementQuarterlyProxy)
class IncomeStatementQuarterlyProxyAdmin(admin.ModelAdmin):
date_hierarchy = 'date'
list_filter = ('line_item',)
list_display = ("ticker", "date", "statement", "line_item", 'amount')
search_fields = ['ticker']
list_display_links = ('ticker',)
def has_add_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False
def has_change_permission(self, request, obj=None) -> bool:
return False
所以我有以下 table:
class IncomeStatementQuarterly(models.Model):
date = models.DateField()
statement = models.CharField(max_length=1000, blank=True, null=True)
ticker = models.CharField(max_length=1000, blank=True, null=True)
security = models.ForeignKey(SecuritiesTable, models.DO_NOTHING)
line_item = models.CharField(max_length=1000, blank=True, null=True)
amount = models.DecimalField(max_digits=65535, decimal_places=4, blank=True, null=True)
class Meta:
ordering=('ticker',)
verbose_name = "Income statement / Quarterly"
verbose_name_plural = "Income statements / Quarterly"
managed = False
db_table = 'income_statement_quarterly'
unique_together = (('date', 'ticker', 'line_item'),)
以及我的 admin.py class 中的以下内容:
@admin.register(IncomeStatementQuarterly)
class IncomeStatementQuarterlyAdmin(admin.ModelAdmin):
date_hierarchy = 'date'
list_filter = ('line_item',)
list_display = ("ticker", "date", "statement", "line_item", 'amount')
search_fields = ['ticker']
list_display_links = ('ticker',)
def has_add_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False
def has_change_permission(self, request, obj=None) -> bool:
return False
我的目标是创建一个按 'ticker' 和 'date' 字段分组的视图。 截至目前,我的管理视图正在显示我模型的每一行 像这样:
我想按代码和日期重新组合所有内容,这样我就会有一个 link 如果单击它,我将拥有基于给定的日期和代码组合的所有行。
这可能吗?
过去 5 天我一直在到处寻找,我正准备开始一个名为 statements_list 的新模型,该模型由我当前模型的字段(代码、日期)的所有独特组合组成这将有一个主键 link 将其与当前模型(日期、代码)字段的唯一组合
我希望这不会太混乱... 基本上最终结果看起来像这样(基于图片上的可用内容):
- 一个 | 2005 年 1 月 31 日 ---> link 所有带有这些参数的语句
- 一个 | 2005 年 4 月 30 日 ---> link 所有带有这些参数的语句
您可以通过覆盖 ModelAdmin class 的 get_queryset() 方法并使用 group_by查询.
queryset = IncomeStatementQuarterly.objects.values('date', 'ticker').annotate(max_id=Max('id'))
In mysql raw query like,
SELECT date, ticker, MAX(id) AS "max_id"
FROM incomestatementquarterly
GROUP BY date, ticker
但是如果您使用 admin default change_list 模板 那么这个查询会给您一个 error。因为 django admin 在模板中渲染值时期望查询集中的 对象列表 和查询集中的 group_by 查询 return 作为 字典列表.
如果你想使用上面的查询,那么你覆盖change_list模板并渲染数据本身。
另一种解法:
另一种获取相同数据的方法,
覆盖 ModelAdmin 的 get_queryset() 方法 class
您的管理员 class ,
@admin.register(IncomeStatementQuarterly)
class IncomeStatementQuarterlyAdmin(admin.ModelAdmin):
list_display = ("ticker", "date", "view_details")
....
....
def get_queryset(self, request):
max_ids_subquery = IncomeStatementQuarterly.objects.values('date', 'ticker').annotate(max_id=Max('id')).values('max_id')
queryset = IncomeStatementQuarterly.objects.filter(id__in=max_ids_subquery)
return queryset
def view_details(self, obj):
date = obj.date
next_date = date + datetime.timedelta(days=1)
url = ("%s?ticker=%s&date__gte=%s&date__lt=%s") % (reverse('admin:your_app_incomestatementquarterlyproxy_changelist'),obj.ticker, date, next_date)
return format_html('<a class="button" href="{}">View</a>',url)
在mysql查询中类似,
SELECT * FROM incomestatementquarterly
WHERE id IN ( SELECT MAX(id) AS "max_id" FROM incomestatementquarterly t1 GROUP BY t1.date, t1.ticker)
您创建了一个代理模型并注册了这个模型,点击查看详细信息您重定向到这个代理模型管理员class,这是确切的 您的模型管理员 class.
class IncomeStatementQuarterlyProxy(IncomeStatementQuarterly):
class Meta:
proxy = True
代理模型管理员class
@admin.register(IncomeStatementQuarterlyProxy)
class IncomeStatementQuarterlyProxyAdmin(admin.ModelAdmin):
date_hierarchy = 'date'
list_filter = ('line_item',)
list_display = ("ticker", "date", "statement", "line_item", 'amount')
search_fields = ['ticker']
list_display_links = ('ticker',)
def has_add_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False
def has_change_permission(self, request, obj=None) -> bool:
return False