#python #django #django-rest-framework
#python #django #django-rest-framework
Вопрос:
У меня есть размещаемая модель, которая имеет внешний ключ для Campaign и Size.
class Campaign(models.Model):
name = models.CharField(max_length=100)
class Size(models.Model):
name = models.CharField(max_length=5)
class ToBePosted(models.Model):
campaign = models.ForeignKey(Campaign, on_delete=models.CASCADE, related_name='to_be_posted_posters')
size = models.ForeignKey(Size, on_delete=models.CASCADE, related_name='to_be_posted_posters')
Мой набор запросов в views.py:
def get_to_be_posted_queryset_with_filter(self, request):
filter_params = ToBePostedParameterConverter(request.GET)
queryset = ToBePosted.objects.all()
return queryset.filter(filter_params.get_filter())
И helpers.py где находится преобразователь ToBePostedParameterConverter
class ParameterConverter:
# Convert url query params to queryset filter params
query_patterns = {
"campaign": 'to_be_posted__campaign__name',
"size": 'reference__size__name',
}
def __init__(self, query_dict):
self._query_dict = query_dict
self._filter_params = []
self._convert()
def _convert(self):
for key in self._query_dict:
for search_key in self._query_dict.getlist(key):
if query_param := self.query_patterns.get(key):
self._filter_params.append(Q(**{query_param: search_key}))
def get_filter(self):
if self._filter_params:
return reduce(operator.or_, self._filter_params)
return Q()
class ToBePostedParameterConverter(ParameterConverter):
query_patterns = {
"campaign": 'campaign__name',
"size": 'size__name',
}
def get_filter(self):
if self._filter_params:
return reduce(operator.or_, self._filter_params)
return Q()
Вопрос в том:
когда я пытаюсь отправить объект размером 666, но связанный только с кампаниями Acamp и Bcamp, я получаю все объекты, размер которых равен 666, независимо от указанных кампаний в URL
ПРИМЕР URL-АДРЕСА ЗАПРОСА С ПАРАМЕТРАМИ:
http://localhost:8000/api/v2/posters/get_lookups/?campaign=Acampamp;campaign=Bcampamp;size=666
Как я могу изменить код, чтобы получать только постеры, связанные с указанными кампаниями в параметрах url?
Я попытался использовать and_
operator в функции reduce. В этом случае он работает правильно, но я не могу указать более одной кампании в URL
Комментарии:
1. Вы хотите сделать что-то вроде этого
return reduce(operator.and_, [reduce(operator.or_,self._size_filter_params),reduce(operator.or_,self._campaign_filter_params)])
2. Есть ли более многоразовый способ реализовать это? Потому что есть некоторые другие параметры фильтра, которые у меня есть