在管理面板中按计算字段排序

Ordering by computed field in admin panel

我正在学习 Django,但遇到了这个问题

我基本上是在尝试通过管理面板视图中的计算字段进行排序,我读过一些像这样的“教程”:https://books.agiliq.com/projects/django-admin-cookbook/en/latest/sorting_calculated_fields.html on google 但我似乎无法理解弄清楚它是如何工作的(在注释等之间)

这是我的 类:

class StockAdmin(admin.ModelAdmin):
list_display = ("ticker_symbol", "security_name", "current_pretax_yield", "current_aftertax_yield", "displayed_price")
search_fields = ("ticker_symbol", "security_name")

def current_pretax_yield(self, obj):
    try:
        curyield = float(obj.coupon_amount/obj.last_price)
        return str(round((curyield*100),3)) + "%"
    except:
        return "n/a"


def current_aftertax_yield(self, obj):
    try:
        withholding_tax = 15
        at_yield = ((obj.coupon_amount/obj.last_price*100)*(1-(withholding_tax/100))*0.74)
        return str(round(at_yield, 2)) + "%"
    except:
        return "n/a"

def get_queryset(self, request):
    queryset = super().get_queryset(request)
    queryset = queryset.annotate(
        _current_aftertax_yield=self.current_aftertax_yield(),
        _current_pretax_yield=self.current_pretax_yield(),
    )

current_aftertax_yield.admin_order_field = '_current_aftertax_yield'
current_pretax_yield.admin_order_field = '_current_pretax_yield'

基本上,我想从数据库中获取“优惠券金额”和“最后价格”字段,执行您在函数中看到的计算,然后在管理面板中显示这些计算文件并能够“按" 他们

我现在的代码因类型错误而出错:current_aftertax_yield() 缺少 1 个必需的位置参数:'obj'

我已经尝试遵循这个:https://books.agiliq.com/projects/django-admin-cookbook/en/latest/sorting_calculated_fields.html 但我自己不太明白..

有什么想法吗?有更简单的方法吗?我在 PHP 中使用了很多计算值,实现起来很简单!

您不能使用方法来注释 Queryset。您应该指定一个 expression 为数据库构造一个表达式。您不能为此使用方法。您可以将 F 表达式与某些聚合等结合使用

这里current_pretax_yieldcurrent_aftertax_yield的比例都是coupon_amount/last_price,所以我们可以做一个注解,然后按那个注解排序:

from django.db.models import <strong>F</strong>

class StockAdmin(admin.ModelAdmin):
    list_display = ("ticker_symbol", "security_name", "current_pretax_yield", "current_aftertax_yield", "displayed_price")
    search_fields = ("ticker_symbol", "security_name")

    def current_pretax_yield(self, obj):
        try:
            curyield = float(obj.coupon_amount/obj.last_price)
            return str(round((curyield*100),3)) + "%"
        except:
            return "n/a"
    
    def current_aftertax_yield(self, obj):
        try:
            withholding_tax = 15
            at_yield = ((obj.coupon_amount/obj.last_price*100)*(1-(withholding_tax/100))*0.74)
            return str(round(at_yield, 2)) + "%"
        except:
            return "n/a"

    def <strong>get_queryset</strong>(self, request):
        return super().get_queryset(request).annotate(
            <strong>_yield=F('coupon_amount')/F('last_price')</strong>
        )

    current_aftertax_yield.admin_order_field = <strong>'_yield'</strong>
    current_pretax_yield.admin_order_field = <strong>'_yield'</strong>