Поставить фильтр на вложенное поле сериализатора DRF
Помогите пожалуйста разобраться. Я создаю api приложение , у меня есть модель магазина, в сериализаторе которого я добавила вложенное поле, ссылающееся на другой сериализатор. Теперь мне нужно добавить фильтр на поле из вложенного сериализатора , но у меня никак не получается. Я попробовала просто добавить поле в фильтры в контроллере , пробовала добавить отдельный класс сериализатор для фильтрации и вызвать этот сериализатор в list_serializer_class в мета классе своего серилизатора , все безрезультатно. Я хочу чтобы при запросе на список магазина, пользователь мог ввести название страны, что-то вроде этого: «url+?country=Россия». Подскажите пожалуйста в каком направлении мне двигаться, документацию прочитала не нашла ответа.
Это мои модели:
class Store(models.Model):
company_name = models.ForeignKey(Retail, on_delete=models.CASCADE, verbose_name='компания')
store_name = models.CharField(max_length=150, verbose_name='название магазина')
supplier = models.ForeignKey(Supplier, on_delete=models.DO_NOTHING, verbose_name='поставщик')
debt_to_supplier = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='Задолженность перед поставщиком в RUB')
creating_date = models.DateTimeField(verbose_name='дата создания', default=now)
objects = models.Manager()
def __str__(self):
return f'{self.store_name}'
class Meta:
verbose_name = 'магазин'
verbose_name_plural = 'магазины'
class Contacts(models.Model):
mail = models.EmailField(max_length=150, verbose_name='почта')
country = models.CharField(max_length=150, verbose_name='страна')
city = models.CharField(max_length=150, verbose_name='город')
street = models.CharField(max_length=150, verbose_name='улица')
house_num = models.CharField(max_length=150, verbose_name='номер дома')
store = models.ForeignKey(Store, on_delete=models.CASCADE, verbose_name='магазин')
objects = models.Manager()
def __str__(self):
return f'{self.mail}'
class Meta:
verbose_name = 'контакт'
verbose_name_plural = 'контакты'
Это сериализаторы:
class Meta:
model = Contacts
fields = '__all__'
class StoreSerializer(serializers.ModelSerializer):
contacts = ContactsSerializer(source='contacts_set', read_only=True, many=True)
products = ProductsSerializer(source='products_set', read_only=True, many=True)
class Meta:
model = Store
fields = ['company_name', 'store_name', 'contacts', 'products', 'debt_to_supplier', 'creating_date']
Это контроллер:
class StoreListApiView(generics.ListAPIView):
queryset = Store.objects.all()
serializer_class = StoreSerializer
pagination_class = StorePaginator
permission_classes = [UserPermissionsAll]
Ответы (1 шт):
Как вариант, вы можете всё же использовать фильтр:
viewset:
from django_filters.rest_framework import DjangoFilterBackend
class StoreListApiView(generics.ListAPIView):
queryset = Store.objects.all()
serializer_class = StoreSerializer
pagination_class = StorePaginator
permission_classes = [UserPermissionsAll]
filter_backends = [DjangoFilterBackend]
# Думаю, что сработает такого плана запрос:
filterset_fields = ['contacts_set__country',]
Попробуйте отправить такой запрос: «url+?contacts_set__country=Россия»
При желании, вы можете изменить имя query-параметра и написать свой фильтр-класс, который преобразует, например, country в contacts_set__country.