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__'