DoggieMurr
@DoggieMurr
Python Enthusiast

Как написать гибкую фильтрацию на Python?

есть таблица в html данные для которой генерируются на бэке. Также для этой таблицы опционально могут примениться фильтры.
Не понимаю, как применять эти фильтры генерируя новые данные для таблицы и не писать 100 условий для каждого случая.
Внешний вид таблицы
64d4a50b5abaa626699054.png

Это как она создается на бэке
def changelist_view(self, request, extra_context=None):
        if extra_context is None:
            extra_context = {}
        week = datetime.date.today() - datetime.timedelta(days=7)
        trial_subscription_id = LessonSubscription.objects.filter(is_trial=True, available=True).first()
        new_users = User.objects.filter(created_at__gte=week)
        form = FunnelSalesFilterForm(initial={'type': None, 'skill_level': None})
        if request.method == 'POST':
            form = FunnelSalesFilterForm(request.POST)
            if form.is_valid():
                print(form.cleaned_data)

        extra_context['form'] = form
        extra_context['from_date'] = week
        extra_context['to_date'] = datetime.date.today()
        extra_context['registration'] = len(new_users)
        extra_context['trial'] = LessonVisitor.objects.filter(
            user__in=new_users,
            lesson__time__lt=datetime.datetime.now(),
            lesson_purchase__lesson_subscription_id=trial_subscription_id.id if trial_subscription_id else None
        ).count()
        extra_context['trial_procent'] = (extra_context['trial'] / len(new_users)) * 100
        extra_context['event'] = EventPurchase.objects.filter(
            first_name__in=new_users.values_list('first_name', flat=True),
            last_name__in=new_users.values_list('last_name', flat=True)
        ).count()
        extra_context['event_procent'] = (extra_context['event'] / extra_context['trial']) * 100
        extra_context['payment'] = LessonPurchase.objects.filter(
            user__in=new_users,
            lesson_subscription__is_trial=False
        ).count()
        extra_context['payment_procent'] = (extra_context['payment'] / extra_context['trial']) * 100
        extra_context['single_subscription'] = LessonPurchase.objects.filter(
            user__in=new_users,
            lesson_subscription__lessons_count=1
        ).count()
        extra_context['single_subscription_procent'] = (extra_context['single_subscription'] /
                                                        extra_context['trial']) * 100
        extra_context['4_flexible'] = LessonPurchase.objects.filter(
            user__in=new_users,
            lesson_subscription__lessons_count=4,
            lesson_subscription__is_flexible=True
        ).count()
        extra_context['4_flexible_procent'] = (extra_context['4_flexible'] / extra_context['trial']) * 100
        extra_context['8_flexible'] = LessonPurchase.objects.filter(
            user__in=new_users,
            lesson_subscription__lessons_count=8,
            lesson_subscription__is_flexible=True
        ).count()
        extra_context['8_flexible_procent'] = (extra_context['8_flexible'] / extra_context['trial']) * 100
        extra_context['16_flexible'] = LessonPurchase.objects.filter(
            user__in=new_users,
            lesson_subscription__lessons_count=16,
            lesson_subscription__is_flexible=True
        ).count()
        extra_context['16_flexible_procent'] = (extra_context['16_flexible'] / extra_context['trial']) * 100
        extra_context['24_flexible'] = LessonPurchase.objects.filter(
            user__in=new_users,
            lesson_subscription__lessons_count=24,
            lesson_subscription__is_flexible=True
        ).count()
        extra_context['24_flexible_procent'] = (extra_context['24_flexible'] / extra_context['trial']) * 100
        extra_context['4_not_flexible'] = LessonPurchase.objects.filter(
            user__in=new_users,
            lesson_subscription__lessons_count=4,
            lesson_subscription__is_flexible=False
        ).count()
        extra_context['4_not_flexible_procent'] = (extra_context['4_not_flexible'] / extra_context['trial']) * 100
        extra_context['8_not_flexible'] = LessonPurchase.objects.filter(
            user__in=new_users,
            lesson_subscription__lessons_count=8,
            lesson_subscription__is_flexible=False
        ).count()
        extra_context['8_not_flexible_procent'] = (extra_context['8_not_flexible'] / extra_context['trial']) * 100
        extra_context['12_not_flexible'] = LessonPurchase.objects.filter(
            user__in=new_users,
            lesson_subscription__lessons_count=12,
            lesson_subscription__is_flexible=False
        ).count()


Это сам html
{% extends "admin/change_list.html" %}
{% load i18n admin_urls static admin_list %}

{% block content %}
    <h2>З {{ from_date }} – {{ to_date }}</h2>
    <form id='the-form'
          method='post'
          action={% url 'export_csv' %}>
        {% csrf_token %}
        <input type='hidden' name='registration' value={{ registration }}>
        <input type='hidden' name='trial' value={{ trial }}>
        <input type='hidden' name='event' value={{ event }}>
        <input type='hidden' name='payment' value={{ payment }}>
        <input type='hidden' name='single_subscription' value={{ single_subscription }}>
        <input type='hidden' name='4_flexible' value={{ 4_flexible }}>
        <input type='hidden' name='8_flexible' value={{ 8_flexible }}>
        <input type='hidden' name='16_flexible' value={{ 16_flexible }}>
        <input type='hidden' name='24_flexible' value={{ 24_flexible }}>
        <input type='hidden' name='4_not_flexible' value={{ 4_not_flexible }}>
        <input type='hidden' name='8_not_flexible' value={{ 8_not_flexible }}>
        <input type='hidden' name='12_not_flexible' value={{ 12_not_flexible }}>
        <input type='hidden' name='24_not_flexible' value={{ 24_not_flexible }}>
        <input type='hidden' name='36_not_flexible' value={{ 36_not_flexible }}>
        <input type='hidden' name='48_not_flexible' value={{ 48_not_flexible }}>
        <input type='hidden' name='trial_procent' value={{ trial_procent }}>
        <input type='hidden' name='event_procent' value={{ event_procent }}>
        <input type='hidden' name='payment_procent' value={{ payment_procent }}>
        <button type="submit">Export
        </button>
    </form>
    <div class="box" style="display: flex; justify-content: space-between">
        <table border="4" width="100%">
            <tr>
                <th>Назва</th>
                <th>Кількість</th>
                <th>Відсоток</th>
            </tr>
            <tr>
                <td>Реєстрацій</td>
                <td>{{ registration }}</td>
                <td>–</td>
            </tr>
            <tr>
                <td>Пробниці які відбулися</td>
                <td>{{ trial }}</td>
                <td>{{ trial_procent }}</td>
            </tr>
            <tr>
                <td>Пробниці, що купили івент</td>
                <td>{{ event }}</td>
                <td>{{ event_procent }}</td>
            </tr>
            <tr>
                <td>Пробниці, що купили або разове, або абонемент</td>
                <td>{{ payment }}</td>
                <td>{{ payment_procent }}</td>
            </tr>
            <tr>
                <td>Покупки разових пробницями</td>
                <td>{{ single_subscription }}</td>
                <td>{{ single_subscription_procent }}</td>
            </tr>
            <tr>
                <td>Покупки пробницями абонементів на 4 без закріплення</td>
                <td>{{ 4_flexible }}</td>
                <td>{{ 4_flexible_procent }}</td>
            </tr>
        </table>
        <form action="." method="POST">
            {% csrf_token %}
            <table>
                {{ form.as_table }}
                <td colspan="2" rowspan="2">
                    <button type="submit">Filter
                    </button>
                </td>
            </table>
        </form>
    </div>

{% endblock %}
  • Вопрос задан
  • 60 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы