【问题标题】:Reverse Filter Django Model with DRF使用 DRF 反向过滤 Django 模型
【发布时间】:2016-11-22 09:37:14
【问题描述】:

我在django-models 中的过滤有问题,我正在使用django-rest-framework 处理这个序列化数据。

我想要在这里获取所有牛群记录,其中动物可能有species_type='Cow' 或空牛群。

这是我的模型。

models.py

class Herd(models.Model):
    name = models.CharField(max_length=25)
    description = models.TextField(max_length=250, null=True)

    created_at = models.DateTimeField(auto_now_add=True, editable=False)
    updated_at = models.DateTimeField(auto_now=True, editable=False)


class Animal(models.Model):
    name = models.CharField(max_length=25)
    species_type = models.CharField(max_length=25)
    breed = models.CharField(max_length=25)

    herd = models.ForeignKey(Herd, related_name='animals', on_delete=models.CASCADE)

    created_at = models.DateTimeField(auto_now_add=True, editable=False)
    updated_at = models.DateTimeField(auto_now=True, editable=False)

serializers.py

class AnimalSerializer(serializers.ModelSerializer):

    class Meta:
        model = Animal
        fields = [
            'name', 
            'species_type', 
            'breed'
          ]
        read_only_fields = ['id', 'created_at', 'updated_at']

class HerdSerializer(serializers.ModelSerializer):
    animals = AnimalSerializer(many=True, read_only=True)

    class Meta:
        model = Herd
        fields = [
            'id',
            'name',
            'description',
            'animals'
        ]
        read_only_fields = ['created_at', 'updated_at']

这是我处理所有 crud 操作的视图集。

views.py

class HerdViewset(viewsets.ModelViewSet):
    """
    This viewset automatically provides `list`, `create`, `retrieve`,
    `update` and `destroy` actions.
    """
    queryset = Herd.objects.all()
    serializer_class = HerdSerializer

现在,当我浏览HerdViewSet 端点/api/herd/ 时,我得到了所有有动物的牛群或空牛群的结果。但是某些畜群中的动物没有过滤species_type='Cow',它仍然返回属于该畜群的所有动物,无论species_type是山羊、绵羊等。

【问题讨论】:

  • 你在哪里制作了过滤器species_type='Cow'
  • @Enix 嗨,它应该在视图集中的这一行 queryset = Herd.objects.all() 中,但遗憾的是我仍然不知道如何做到这一点,因为我的 Herd 模型中没有野外动物,不像在我的HerdSerializer
  • @ShiftN'Tab 如果您需要根据species_type='Cow'进行动物过滤的所有畜群数据,那么您需要更新模型结构和字段之间的关系。

标签: python django django-models django-rest-framework


【解决方案1】:

您可以通过 Herd 中的species_type 进行过滤。因为你在外键中定义了related_name

试试这个

from django.db.models import Count, Q

Herd.objects.annotate(animalCount=Count('animals')).filter(Q(animals__species_type='Cow')|Q(animalCount=0))
  1. annotate 用于在结果中添加一个额外字段,因此一个新字段 animalCount 用于保存该畜群的动物数量。
  2. Q 用于构建复杂的查询条件,所以对于这种情况,Q(animals__species_type='Cow')|Q(animalCount=0) 的意思是,按物种类型为“牛”的畜群中的动物进行过滤,或者该畜群中没有动物。

【讨论】:

  • @PrakharTrivedi 不是animal,而是animals。它确实存在...因为他在foreign key field 中定义了related_name。我已经在我的机器上测试了这段代码...
  • @Enix 你有个好主意,但出了点问题,我无法显示空牛群。
  • @ShiftN'Tab empty herd 是什么意思?你的意思是过滤结果不存在?
  • @Enix 过滤结果存在,我可以显示所有有动物的牛群,其中他们的种类_type='Cow' 但我也想显示没有动物的牛群。
  • @ShiftN'Tab 所以.. 你需要按species_type 过滤,否则牛群是空的?对吗?
猜你喜欢
  • 1970-01-01
  • 2020-01-14
  • 2016-02-23
  • 2015-07-25
  • 2020-11-15
  • 2021-01-05
  • 2018-08-02
  • 1970-01-01
  • 2023-03-13
相关资源
最近更新 更多