【问题标题】:Filtering by query params in many to many relationship using drf使用 drf 在多对多关系中按查询参数过滤
【发布时间】:2021-12-03 18:47:41
【问题描述】:

我有两个模型:

class Book(models.Model):
    id = models.CharField(verbose_name="unique id", primary_key=True, max_length=256)
    title = models.CharField(max_length=256)
    published_date = models.CharField(max_length=128, blank=True, null=True)
    average_rating = models.IntegerField(blank=True, null=True, default=None)
    ratings_count = models.IntegerField(blank=True, null=True, default=None)
    thumbnail = models.URLField(verbose_name="thumbnail url", null=True, blank=True, default=None)

class Author(models.Model):
    name = models.CharField(null=True, blank=True, max_length=256)
    books = models.ManyToManyField(Book, related_name='authors')

我想要实现的是我想通过使用这样的查询参数来过滤 api 查询:

127.0.0.1/books?author='something'

所以我的参数就是那种情况。

我想按作者姓名过滤并检查是否有与该作者有关系的书籍。同样重要的是,一次可能有不止一个参数,如下所示:

?author='something1'&author='something2'

我不知道如何实现这一点。我正在尝试在 DRF 的通用类中使用 get_queryset 函数进行默认过滤,但仍然不知道。

【问题讨论】:

  • 您是否实现了更简单的过滤器,例如/books?title="I, Robot"?如果没有,我建议您先这样做,这样您就可以了解基本过滤,然后在此基础上实现对多对多字段的过滤。

标签: python django url django-rest-framework


【解决方案1】:

正确的方法是使用django-filter: https://django-filter.readthedocs.io/en/stable/guide/install.html

像这样:

class BookFilterSet(filters.FilterSet):
    
    class Meta:
        model = Book
        fields = ['authors']

class BookViewSet(ModelViewSet):
    serializer_class = BookSerializer
    queryset = Book.objects.all()
    filter_backends = [filters.DjangoFilterBackend]
    filterset_class = BookFilterSet

【讨论】:

    【解决方案2】:

    这应该可以使用 DjangoFilterBackend 轻松完成。

    您可以尝试按照here的步骤操作

    在通用过滤下。

    如果这不起作用 - 您可以尝试使用第三方软件包,例如 django-filters :) 让我知道它是怎么回事 :)

    【讨论】:

    【解决方案3】:

    好的,所以基本上我按照你们的建议使用了 django-filters 包,但是我不知道如何实现通过同一个查询键多次过滤的效果。

    我的意思是,如果有人会尝试按这样的几个作者姓名进行过滤:

    ?author=tolkien&author=jan

    那么如何通过“tolkien”和“jan”这两个值过滤数据库?

    我的过滤器集如下所示:

    class BookFilter(filters.FilterSet):
        author = filters.CharFilter(field_name='authors__name' ,lookup_expr='icontains')
        categories__name = filters.CharFilter(lookup_expr='icontains')
        published_date = filters.CharFilter(lookup_expr='icontains')
    
        class Meta:
            model = Book
            fields = ['author', 'categories__name', 'published_date']
    

    并像这样查看函数:

    class BooksView(generics.ListAPIView):
        queryset = Book.objects.all()
        serializer_class = BooksSerializer
        filter_backends = [filters.DjangoFilterBackend,]
        filterset_class = BookFilter
    

    我想要实现的效果是获取作者是姓名包含 jan 或 tolkien 的书籍的查询集

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-01
      • 2020-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-17
      • 2013-09-14
      • 1970-01-01
      相关资源
      最近更新 更多