在Django Rest Framework中将自定义过滤字段转储为响应

时间:2016-04-03 08:27:49

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

博客/ models.py

class Tag(models.Model):
    label = models.SlugField(null=False, blank=False, unique=True)
    # (iii) or here?

# ...

class Entry(models.Model):
    title = models.CharField(null=False, blank=False, max_length=128)
    content = models.TextField(null=False, blank=False)
    slug = models.SlugField(unique=True)
    tags = models.ManyToManyField(Tag, null=False, blank=False)
    dtime_created = models.DateTimeField(null=False, blank=False, auto_now_add=True)

API / serializers.py

from blog.models import *

from rest_framework import serializers

class EntrySerializer(serializers.ModelSerializer):
    class Meta:
        model = Entry
        fields = ("title", "content")

class TagSerializer(serializers.ModelSerializer):
    class Meta:
        model = Tag
        fields = ("label")
        # (ii) here?

API / views.py

class TagList(APIView):
    def search_by_query(self, query):
        try:
            return Tag.objects.filter(label__icontains=re.escape(query))
            # (i) do something here?
        except Tag.DoesNotExist:
            raise Http404

    def get(self, request, format=None):
        q = None
        try:
            q = request.POST["q"]
        except KeyError:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        tags = self.search_by_query(query)
        serializer = TagSerializer(tags, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        if not request.user.is_authenticated():
            return Response(status=status.HTTP_403_FORBIDDEN)

        serializer = TagSerializer(request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

我的问题有点复杂。现在,我有一个由Tag模型使用的Entry模型。然后,我创建了一个名为APIView的{​​{1}},它转储包含标签的字符串。但是,问题是,我还要转储TagList实例中使用标记的次数,如下所示:

Entry

怎么做?

环境

  • python 3.5.1
  • django 1.9.5
  • djangorestframework 3.3.3

1 个答案:

答案 0 :(得分:1)

非常简单 - 使用DRF的source核心参数。

第1步

Tag模型上定义一个计算任何标记出现次数的方法:

class Tag(models.Model):
    label = models.SlugField(null=False, blank=False, unique=True)

    def nr_of_entries(self):
        return self.entry_set.count()

第2步

然后在TagSerializer上添加一个自定义字段,该字段将从您在上面定义的方法中获取数据:

class TagSerializer(serializers.ModelSerializer):
    length = serializers.IntegerField(source="nr_of_entries", read_only=True)
    class Meta:
        model = Tag
        fields = ("label", "length")

现在,当序列化tag的实例时,它将包含length属性,该属性将从在{{nr_of_entries方法上运行tag方法的结果中获取其值1}}实例。