Home > Software design >  Django-Filter Use lookup_choices for custom results
Django-Filter Use lookup_choices for custom results

Time:10-02

I have a field profit_loss_value_fees and in this field I would like the user to have a drop-down option to show all trades that were a Profit/Loss/Scratch.

Profit = Trade.profit_loss_value_fees > 0
Loss = Trade.profit_loss_value_fees < 0
Scratch = Trade.profit_loss_value_fees == 0 

What I have done is a result1 which works but I don't get a nice drop-down as mentioned above. It's two empty fields where a user could type in say 1 and 100 and then all trades in that range show. It works but not the desired look.

filters.py

class StatsPortfolioFilter(django_filters.FilterSet):

    # Drop down with 3 options (Win, Loss, Scratch) using the Trade Field: profit_loss_value_fees
    result1 = django_filters.RangeFilter(
        field_name='profit_loss_value_fees',
        label='result1',
        )

What I tried is using the LookupChoiceFilter to create the 3 drop-down options and that worked. The problem is the options do not do anything, obviously. How can I add

filters.py

class StatsPortfolioFilter(django_filters.FilterSet):

    # I need something that gives the lookup_choices value
    # w = Trade.profit_loss_value_fees > 0
    # l = Trade.profit_loss_value_fees < 0
    # s = Trade.profit_loss_value_fees == 0

    # Drop down with 3 options (Win, Loss, Scratch) using the Trade Field: profit_loss_value_fees
    result = django_filters.LookupChoiceFilter(
        field_name='profit_loss_value_fees', # field_name focuses on field relatetion
        label='Result',
        # field_class=forms.DecimalField,
        lookup_choices=[
            ('w', 'Win'),
            ('l', 'Loss'),
            ('s', 'Scratch'),
        ]
    )

There are no error messages as of yet because I am stuck on how to proceed.

CodePudding user response:

Try to do custom filter field and method to get correct query as follow

class StatsPortfolioFilter(django_filters.FilterSet):
   WIN_LOSS_CHOICES = (
            ('w', 'Win'),
            ('l', 'Loss'),
            ('s', 'Scratch'),
        )
   result = django_filters.ChoiceFilter(empty_label='---------', label="Result", 
       choices=WIN_LOSS_CHOICES, method="trade_win_loss")

   def trade_win_loss(self, queryset, name, value):
        if (value == 'w'):
            return queryset.filter(profit_loss_value_fees__gt=0)
        if (value == 'l'):
            return queryset.filter(profit_loss_value_fees__lt=0)
        if (value == 's'):
            return queryset.filter(profit_loss_value_fees= 0)

        return queryset
  • Related