Как правильно отфильтровать через связанное поле ManyToMany с помощью django-filters?

Ссылка скопирована
1 ответ

Есть модель Book и Category. Они связаны через поле category в модели Book.

При фильтрации с помощью django-filters по полю `categories` выдает все записи. Я делаю что-то не так, но не знаю что.

models.py

from django.db import models   class Category(models.Model):     title = models.TextField()   class Book(models.Model):     title = models.TextField()     isbn = models.TextField(null=True, blank=True)     pagecount = models.IntegerField(null=True, blank=True)     publisheddate = models.TextField(null=True, blank=True)     thumbnailurl = models.TextField(null=True, blank=True)     shortdescription = models.TextField(null=True, blank=True)     longdescription = models.TextField(null=True, blank=True)     status = models.TextField()     authors = models.JSONField()     categories = models.ManyToManyField(         Category,         blank=True     )

from django.db import models class Category(models.Model): title = models.TextField() class Book(models.Model): title = models.TextField() isbn = models.TextField(null=True, blank=True) pagecount = models.IntegerField(null=True, blank=True) publisheddate = models.TextField(null=True, blank=True) thumbnailurl = models.TextField(null=True, blank=True) shortdescription = models.TextField(null=True, blank=True) longdescription = models.TextField(null=True, blank=True) status = models.TextField() authors = models.JSONField() categories = models.ManyToManyField( Category, blank=True )

views.py

from rest_framework.viewsets import ReadOnlyModelViewSet from rest_framework.generics import CreateAPIView, ListAPIView from django_filters.rest_framework import DjangoFilterBackend  from api.models import Book, Category, FeedBack from api.serializers import BookSerializer, CategorySerializer, FeedBackSerializer from api.filters import BookFilter   class ListRetrieveBook(ReadOnlyModelViewSet):     """     Получение всех книг, книг по категории, конкретной книги.     """      queryset = Book.objects.all()     serializer_class = BookSerializer     filter_backends = (DjangoFilterBackend,)     filterset_fields = ('categories__title',)

from rest_framework.viewsets import ReadOnlyModelViewSet from rest_framework.generics import CreateAPIView, ListAPIView from django_filters.rest_framework import DjangoFilterBackend from api.models import Book, Category, FeedBack from api.serializers import BookSerializer, CategorySerializer, FeedBackSerializer from api.filters import BookFilter class ListRetrieveBook(ReadOnlyModelViewSet): """ Получение всех книг, книг по категории, конкретной книги. """ queryset = Book.objects.all() serializer_class = BookSerializer filter_backends = (DjangoFilterBackend,) filterset_fields = ('categories__title',)

В общем, если делаю фильтрацию по id: filterset_fields = ('categories',), то фильтрует норм, а если filterset_fields = ('categories__title',), то просто возвращает все записи.

Дополнительно:

Я допустил, ошибку, неправильно делая запрос:

http://127.0.0.1:8000/api/v1/books?categories=<Название категории>

http://127.0.0.1:8000/api/v1/books?categories=<Название категории>

Сработал запрос вида:

http://127.0.0.1:8000/api/v1/books?categories__title=<Название категории>

http://127.0.0.1:8000/api/v1/books?categories__title=<Название категории>

Может кому то поможет..

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Максим Павлов Ответ

Для правильного фильтрования через связанное поле ManyToMany с помощью django-filters, необходимо создать собственный фильтр, который будет учитывать связанные объекты.

Для начала, убедитесь, что у вас есть модель с полем ManyToMany, которое вы хотите фильтровать, и что у вас установлен django-filters.

Затем создайте новый файл filters.py в вашем приложении и импортируйте необходимые модули:

from django_filters import FilterSet, ModelMultipleChoiceFilter
from .models import YourModel

from django_filters import FilterSet, ModelMultipleChoiceFilter from .models import YourModel

Создайте класс фильтра, который будет наследоваться от FilterSet и определите в нем поле ManyToMany, которое вы хотите фильтровать:

class YourModelFilter(FilterSet):
    field_name = ModelMultipleChoiceFilter(queryset=YourModel.objects.all())

class YourModelFilter(FilterSet): field_name = ModelMultipleChoiceFilter(queryset=YourModel.objects.all())

Затем добавьте этот фильтр к вашему представлению, используя django-filters:

from django_filters.views import FilterView
from .filters import YourModelFilter
 
class YourModelListView(FilterView):
    model = YourModel
    filterset_class = YourModelFilter
    template_name = 'your_template.html'

from django_filters.views import FilterView from .filters import YourModelFilter class YourModelListView(FilterView): model = YourModel filterset_class = YourModelFilter template_name = 'your_template.html'

Теперь вы можете использовать ваш фильтр в шаблоне вашего представления:

 
    {{ filter.form }}
    <button type="submit">Filter</button>
 
 
{% for object in filter.qs %}
    {{ object }}
{% endfor %}

{{ filter.form }} <button type="submit">Filter</button> {% for object in filter.qs %} {{ object }} {% endfor %}

Теперь у вас должен быть рабочий фильтр ManyToMany, который позволяет пользователям фильтровать объекты по связанным полям. Не забудьте провести тестирование, чтобы убедиться, что фильтр работает корректно.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно