Добавлен фильтр 'Есть канал связи' в список клиентов

- Новый фильтр has_contact_channel показывает клиентов с записями в ContactChannel
- Проверяет наличие альтернативных контактов (Instagram, Telegram и т.д.)
- Добавлен чекбокс в форму фильтров с flex-wrap для переноса
- Обновлено условие показа кнопки Очистить
- Фильтр автоматически сохраняется в пагинации через url_replace
This commit is contained in:
2026-01-03 15:38:22 +03:00
parent 36cca23b60
commit e6fd44ef6b
2 changed files with 25 additions and 3 deletions

View File

@@ -38,9 +38,16 @@ class CustomerFilter(django_filters.FilterSet):
widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}) widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
) )
# Фильтр: есть канал связи
has_contact_channel = django_filters.BooleanFilter(
method='filter_has_contact_channel',
label='Есть канал связи',
widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
)
class Meta: class Meta:
model = Customer model = Customer
fields = ['has_notes', 'no_phone', 'no_email'] fields = ['has_notes', 'no_phone', 'no_email', 'has_contact_channel']
def filter_has_notes(self, queryset, name, value): def filter_has_notes(self, queryset, name, value):
"""Фильтр клиентов с заметками""" """Фильтр клиентов с заметками"""
@@ -59,3 +66,12 @@ class CustomerFilter(django_filters.FilterSet):
if value: if value:
return queryset.filter(email__isnull=True) | queryset.filter(email='') return queryset.filter(email__isnull=True) | queryset.filter(email='')
return queryset return queryset
def filter_has_contact_channel(self, queryset, name, value):
"""Фильтр клиентов с каналами связи (Instagram, Telegram и т.д.)"""
if value:
from .models import ContactChannel
# Возвращаем только клиентов у которых есть хотя бы один канал связи
customer_ids = ContactChannel.objects.values_list('customer_id', flat=True).distinct()
return queryset.filter(id__in=customer_ids)
return queryset

View File

@@ -41,7 +41,7 @@
<!-- Фильтры --> <!-- Фильтры -->
<div class="col-md-6"> <div class="col-md-6">
<div class="d-flex gap-3 align-items-center"> <div class="d-flex gap-3 align-items-center flex-wrap">
<div class="form-check"> <div class="form-check">
{{ filter.form.has_notes }} {{ filter.form.has_notes }}
<label class="form-check-label" for="{{ filter.form.has_notes.id_for_label }}"> <label class="form-check-label" for="{{ filter.form.has_notes.id_for_label }}">
@@ -60,6 +60,12 @@
Нет email Нет email
</label> </label>
</div> </div>
<div class="form-check">
{{ filter.form.has_contact_channel }}
<label class="form-check-label" for="{{ filter.form.has_contact_channel.id_for_label }}">
Есть канал связи
</label>
</div>
</div> </div>
</div> </div>
@@ -69,7 +75,7 @@
<button type="submit" class="btn btn-primary"> <button type="submit" class="btn btn-primary">
<i class="bi bi-search"></i> Поиск / Фильтр <i class="bi bi-search"></i> Поиск / Фильтр
</button> </button>
{% if query or filter.form.has_notes.value or filter.form.no_phone.value or filter.form.no_email.value %} {% if query or filter.form.has_notes.value or filter.form.no_phone.value or filter.form.no_email.value or filter.form.has_contact_channel.value %}
<a href="{% url 'customers:customer-list' %}" class="btn btn-outline-secondary"> <a href="{% url 'customers:customer-list' %}" class="btn btn-outline-secondary">
<i class="bi bi-x-circle"></i> Очистить <i class="bi bi-x-circle"></i> Очистить
</a> </a>