Django-фильтр нескольких внешних ключей из одной модели

У меня есть модель с 2 полями place_of_loading и place_of_unloading с внешним ключом к одной и той же модели ConstructionSite.

class DailyPerformance(models.Model):
  date = models.DateField()
  driver = models.ForeignKey(Employee, on_delete=models.CASCADE)
  TYPE_OF_GOODS_CHOICES = (
    ("Excavated soil", "Excavated soil"),
    ("Sand", "Sand"),
    ("Crushed stone", "Crushed stone"),...
  )
  type_of_goods = models.CharField(blank=True, null=True, max_length=30, choices=TYPE_OF_GOODS_CHOICES)
  place_of_loading = models.ForeignKey(ConstructionSite, on_delete=models.CASCADE, related_name='place_of_loading')
  place_of_unloading = models.ForeignKey(ConstructionSite, on_delete=models.CASCADE, related_name='place_of_unloading') 
  number_of_rounds = models.IntegerField(blank=True, null=True)

Теперь я хочу реализовать фильтр с помощью django-filters, но я хочу вместо 2 полей place_of_loading и place_of_unloading иметь 1 поле construction_site и показывать результаты по обоим полям. Таким образом, если я выбираю одно место строительства, я хочу получить всю информацию о погрузке и разгрузке материалов.

class DailyPerformanceFilter(django_filters.FilterSet):
    date = DateFilter(field_name='date', widget=DateInput(attrs={'type': 'date'}))
    start_date = DateFilter(field_name='date', lookup_expr='gte')
    end_date = DateFilter(field_name='date', lookup_expr='lte')
    place_of_loading = django_filters.ModelChoiceFilter(queryset = ConstructionSite.objects.all(), widget=forms.Select(attrs={'class': 'filter-select'}))
    place_of_unloading = django_filters.ModelChoiceFilter(queryset = ConstructionSite.objects.all(), widget=forms.Select(attrs={'class': 'filter-select'}))
    construction_site = django_filters.ModelChoiceFilter(queryset = ConstructionSite.objects.all(), widget=forms.Select(attrs={'class': 'filter-select'}))
    class Meta:
        model = DailyPerformance
        fields = '__all__'

Мы можем использовать параметр method= [readthedocs.io] для настройки фильтрации и поиска обоих полей:

from django.db.models import Q


class DailyPerformanceFilter(django_filters.FilterSet):
    date = DateFilter(field_name='date', widget=DateInput(attrs={'type': 'date'}))
    start_date = DateFilter(field_name='date', lookup_expr='gte')
    end_date = DateFilter(field_name='date', lookup_expr='lte')
    place_of_loading = django_filters.ModelChoiceFilter(
        queryset=ConstructionSite.objects.all(),
        widget=forms.Select(attrs={'class': 'filter-select'}),
    )
    place_of_unloading = django_filters.ModelChoiceFilter(
        queryset=ConstructionSite.objects.all(),
        widget=forms.Select(attrs={'class': 'filter-select'}),
    )
    construction_site = django_filters.ModelChoiceFilter(
        queryset=ConstructionSite.objects.all(),
        widget=forms.Select(attrs={'class': 'filter-select'}),
        method='filter_construction_site',
    )

    def filter_construction_site(self, queryset, name, value):
        return queryset.filter(
            Q(place_of_loading=value) | Q(place_of_unloading=value)
        )

    class Meta:
        model = DailyPerformance
        fields = '__all__'
Вернуться на верх