如何在阵列上创建过滤器查询集以便需要所有搜索项?

时间:2017-08-22 15:20:48

标签: django django-rest-framework django-taggit

我有一个带有标签的Photo模型。我希望能够创建一个查询,以便只返回具有所有搜索标签条款的照片。当前行为(使用下面的视图代码)返回的照片中包含任何正在搜索的标签。

@list_route(methods=['post'])
def tags(self, request):
    """
    search for entities by tags they contain
    :param request:
    :return: Response
    """
    tags = json.loads(request.data['tags'])
    photos = Photo.objects.filter(tags__name__in=tags, owner=self.request.user).distinct()
    page = self.paginate_queryset(photos)
    if page is not None:
        serializer = self.get_serializer(page, many=True)
        return self.get_paginated_response(serializer.data)

    serializer = self.get_serializer(photos, many=True)
    return Response(
        data=serializer.data
    )

这是模型类:

class Photo(TimestampModerated):
    owner = models.ForeignKey('auth.User', related_name='photos', on_delete=models.CASCADE)
    uuid = models.UUIDField(default=uuid4, editable=False)
    slug = models.SlugField(max_length=80, editable=False)
    title = models.CharField(max_length=80, blank=False, null=False)
    description = models.TextField(verbose_name='description of entity', blank=True, null=True)
    photo = models.ImageField(upload_to=user_directory_path, height_field="height", width_field="width", blank=True)
    height = models.IntegerField(blank=True)
    width = models.IntegerField(blank=True)
    tags = TaggableManager(blank=True)
    hash = models.CharField(max_length=64, unique=True, null=True)

    class Meta:
        verbose_name_plural = "photos"

    def __str__(self):
        return self.title

    def delete(self, using=None, keep_parents=False):
        default_storage.delete("{}".format(self.photo))
        super().delete()

    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        super(Photo, self).save(*args, **kwargs)

我使用django-rest-framework创建视图,使用django-taggit进行标记。

1 个答案:

答案 0 :(得分:1)

一种方法是循环添加filter条款的术语列表:

photos = Photos.objects.filter(owner=self.request.user)
for tag in tags:
    photos = photos.filter(tags__name=tag)
photos = photos.distinct()

组合Q对象不适用于此,因为docs解释Django要求同一个相关对象满足单个filter子句中的所有约束 - {{1}多个AND对象组合在一起需要一个标签的名称等于列表中的每个术语。