【问题标题】:How to take slice of string when serializing a field (Django/DRF)序列化字段时如何获取字符串片段(Django / DRF)
【发布时间】:2019-01-20 16:15:12
【问题描述】:

第一次在这里问,我会尽量听起来很聪明! 因此,我有一个名为“Article”的模型,并在其“文本”字段中填充了 1000 多个字符的文本。当我通过端点发送“文章”序列化对象时,我怎样才能做到只发送“文本”字段的前 200 个字符?

views.py

class ArticleScrape(generics.ListAPIView):                                                                                                                                                                          
    queryset = Article.objects.all()                                                                                                                                                                                
    serializer_class = ArticleSerializer                                                                                                                                                                            

    def list(self,request):                                                                                                                                                                           
        serializer = ArticleSerializer(queryset, many=True)                                                                                                                                                         
        return Response(serializer.data) 

序列化器.py

class ArticleSerializer(serializers.ModelSerializer):                                                                                                                                                               
    authors = EachAuthorSerializer(many=True,read_only=True)                                                                                                                                                        
    tags = EachTagSerializer(many=True,read_only=True)                                                                                                                                                              
    text = serializers.CharField(max_length=200)                                                                                                                                                                    
    class Meta:                                                                                                                                                                                                     
        model = Article                                                                                                                                                                                             
        exclude=('id',) 

我需要在查询集中执行这个操作吗?在序列化器中?我要注释一个字段吗?我已经尝试了很多,但没有成功。提前感谢您的帮助!

【问题讨论】:

  • 您的意思是只返回 API 响应中 text 字段的前 200 个字符?
  • 没错!这就是我想要的

标签: python django django-rest-framework


【解决方案1】:

有不同的方法,我更喜欢的第一个是将属性添加到模型并将其字段添加到序列化器:

class Article(models.Modle):
    ...
    @property
    def summary(self):
        return self.text[:200]


class ArticleSerializer(serializers.ModelSerializer):                                                                                                                                                               
    summary = serializers.CharField()                                                                                                                                                        

对于第二种方法,您可以使用 SerializerMethodField:

class ArticleSerializer(serializers.ModelSerializer):                                                                                                                                                               
    summary = serializers.SerializerMethodField() 

    def get_summary(self, obj):
        return obj.text[:200]

【讨论】:

  • 这很干净。我最终混合使用了另外两个 SO 答案:annotating a fieldgetting a substring。对我来说,很难吸收所有在 Django 中可以做同样事情的方法。很高兴有选择,但它是如此压倒性......
【解决方案2】:

另一种方法是创建您自己的自定义字段:

class CustomCharField(serializers.CharField):

    def __init__(self, repr_length, **kwargs):
        self.repr_length = repr_length
        super(CustomCharField, self).__init__(**kwargs)

    def to_representation(self, value):
        return super(CustomCharField, self).to_representation(value)[:self.repr_length]

并在序列化程序中使用它:

class ArticleSerializer(serializers.ModelSerializer):
    text = CustomCharField(repr_length=200)

【讨论】:

  • 我明白了,这看起来很聪明,而且根本不涉及数据库
【解决方案3】:

我喜欢 zeynel 建议的“CustomCharField”方法。此版本使用 Django 的Truncator

from django.utils.text import Truncator
from rest_framework import serializers

class TruncatedCharField(serializers.CharField):
    def __init__(self, length=200, **kwargs):
        self.length = length
        super().__init__(**kwargs)

    def to_representation(self, value):
        repr_ = super().to_representation(value)
        return Truncator(repr_).chars(self.length)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    • 1970-01-01
    • 2018-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多