diff --git a/myproject/customers/filters.py b/myproject/customers/filters.py new file mode 100644 index 0000000..c7becba --- /dev/null +++ b/myproject/customers/filters.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +""" +Фильтры для клиентов с использованием django-filter +""" + +import django_filters +from django import forms +from .models import Customer + + +class CustomerFilter(django_filters.FilterSet): + """ + Фильтр для списка клиентов + Поддерживает фильтрацию по: + - Наличию заметок + - Отсутствию телефона + - Отсутствию email + """ + + # Фильтр: есть заметки + has_notes = django_filters.BooleanFilter( + method='filter_has_notes', + label='Есть заметки', + widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}) + ) + + # Фильтр: нет телефона + no_phone = django_filters.BooleanFilter( + method='filter_no_phone', + label='Нет телефона', + widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}) + ) + + # Фильтр: нет email + no_email = django_filters.BooleanFilter( + method='filter_no_email', + label='Нет email', + widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}) + ) + + class Meta: + model = Customer + fields = ['has_notes', 'no_phone', 'no_email'] + + def filter_has_notes(self, queryset, name, value): + """Фильтр клиентов с заметками""" + if value: + return queryset.filter(notes__isnull=False).exclude(notes='') + return queryset + + def filter_no_phone(self, queryset, name, value): + """Фильтр клиентов без телефона""" + if value: + return queryset.filter(phone__isnull=True) | queryset.filter(phone='') + return queryset + + def filter_no_email(self, queryset, name, value): + """Фильтр клиентов без email""" + if value: + return queryset.filter(email__isnull=True) | queryset.filter(email='') + return queryset diff --git a/myproject/customers/templates/customers/customer_list.html b/myproject/customers/templates/customers/customer_list.html index 2ea2508..8fdfbb6 100644 --- a/myproject/customers/templates/customers/customer_list.html +++ b/myproject/customers/templates/customers/customer_list.html @@ -27,21 +27,48 @@ - +
-
-
+ + +
-
-
+ + +
+
+
+ {{ filter.form.has_notes }} + +
+
+ {{ filter.form.no_phone }} + +
+
+ {{ filter.form.no_email }} + +
+
+
+ + +
+
- {% if query %} + {% if query or filter.form.has_notes.value or filter.form.no_phone.value or filter.form.no_email.value %} Очистить diff --git a/myproject/customers/views.py b/myproject/customers/views.py index 874e92e..23ab481 100644 --- a/myproject/customers/views.py +++ b/myproject/customers/views.py @@ -13,6 +13,7 @@ import json from decimal import Decimal from .models import Customer, ContactChannel from .forms import CustomerForm, ContactChannelForm +from .filters import CustomerFilter def normalize_query_phone(q): @@ -33,6 +34,10 @@ def customer_list(request): # Исключаем системного клиента из списка customers = Customer.objects.filter(is_system_customer=False) + # Применяем фильтры django-filter + customer_filter = CustomerFilter(request.GET, queryset=customers) + customers = customer_filter.qs + if query: # Нормализуем номер телефона phone_normalized = normalize_query_phone(query) @@ -79,6 +84,7 @@ def customer_list(request): 'page_obj': page_obj, 'query': query, 'total_customers': paginator.count, # Используем count из paginator, чтобы избежать дублирования SQL запроса + 'filter': customer_filter, # Добавляем фильтр в контекст } return render(request, 'customers/customer_list.html', context)