Упорядочивание по вычисляемому полю в панели администратора

Я изучаю Django и застрял на этой проблеме

Я пытаюсь сделать порядок по вычисляемому полю в представлении панели администратора, я прочитал несколько "туториалов" вроде этого: https://books.agiliq.com/projects/django-admin-cookbook/en/latest/sorting_calculated_fields.html в 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'

В основном, я хочу получить поля "сумма купона" и "последняя цена" из базы данных, выполнить вычисления, которые вы видите в функциях, затем отобразить эти вычисленные файлы в панели администратора и иметь возможность "заказать по ним"

Код в том виде, в котором он у меня сейчас, выдает ошибку TypeError: current_aftertax_yield() missing 1 required positional argument: 'obj'

Я пытался следовать этому: https://books.agiliq.com/projects/django-admin-cookbook/en/latest/sorting_calculated_fields.html но не могу разобраться самостоятельно...

Есть идеи? Есть ли более простой способ сделать это? Я использовал много вычисляемых значений в PHP и это было тривиально реализовать!

Вы не можете использовать методы для аннотирования Queryset. Вы должны указать выражение, построенное выражение для базы данных. Вы не можете использовать для этого метод. Вы можете использовать комбинации Fвыражений вместе с определенными агрегатами и т.д.

Здесь и current_pretax_yield, и current_aftertax_yield масштабируются с coupon_amount/last_price, поэтому мы можем сделать аннотацию, а затем сортировать по этой аннотации:

from django.db.models import F

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):
        return super().get_queryset(request).annotate(
            _yield=F('coupon_amount')/F('last_price')
        )

    current_aftertax_yield.admin_order_field = '_yield'
    current_pretax_yield.admin_order_field = '_yield'
Вернуться на верх