Search code examples
djangodjango-filter

Using django_property_filter but PropertyChoiceFilter failing to match on Inactive


I can't figure out what I'm doing wrong here. I'm using django_property_filter to add a filter to my list of employees.

I have an Employee model to extend the User model. It has a property of is_active to return the user model's is_active value.

class Employee(models.Model):
"""Model representing an employee - one-to-one with user"""
user = models.OneToOneField(User, on_delete=models.CASCADE)

@property
def is_active(self):
    """Property to return active status of user to employee model"""
    return self.user.is_active  

I have a propertyfilter using django_property_filter

class EmployeeFilter(PropertyFilterSet):

ACTIVE_CHOICES = (
(True, 'Active'),
(False, 'Inactive'),
)

active = PropertyChoiceFilter(choices=ACTIVE_CHOICES,field_name='is_active',lookup_expr='exact',label='Active')

class Meta:
    model = Employee
    fields = ['locations']

I'm using a function based view to list all employees.

def EmployeesList(request):
    
employee=getemployeefromuser(request)
if employee:
    
    emp_list = Employee.objects.filter(hotel__exact=employee.hotel).order_by('user')
    f = EmployeeFilter(request.GET, queryset=emp_list)
    emp_list = f.qs
     
    paginator = Paginator(emp_list, 20)
    page = request.GET.get('page', 1)
    try:
       emps = paginator.page(page)
    except PageNotAnInteger:
       emps = paginator.page(1)
    except EmptyPage:
       emps = paginator.page(paginator.num_pages)

    context = {
    'filter':f,
    'emps':emps,
    }

return render(request, 'staffapp/employee_list.html', context=context)

The filters display as expected. The location filter works correctly. The active filter works correctly for ----/None and Active/True but when I select Inactive it just returns the same results as Active. The URL correctly appends "?Active=False" but the resulting employee records are the same as when it appends "?Active=True".

Update: I can get this to functionally work if I use PropertyBooleanFilter instead of PropertyChoiceFilter. But the options presented to the user are confusing (Unknown/Yes/No) so it's functional but not practical.

#this works but options unknown/yes/no are not intuitive to users
isactive = PropertyBooleanFilter(field_name='is_active',lookup_expr='exact',label='Active')

I haven't found any way to override the dropdown options for PropertyBooleanFilter.


Solution

  • Confirmed with developer of django_property_filter that this is a defect.

    Suggested workaround is to use a boolean widget with property_boolean_filter instead.

    ACTIVE_CHOICES = (
    (None, 'All'),
    (True, 'Active'),
    (False, 'Inactive'),
    )
    my_widget = BooleanWidget()
    my_widget.choices = ACTIVE_CHOICES
    
    isactive = PropertyBooleanFilter(widget=my_widget, 
    field_name='is_active',lookup_expr='exact',label='Active')