4

django rest フレームワークを使用して、記事のコンテンツを出力しています。完全な「コンテンツ」を返すのではなく、ティーザー(コンテンツの最初の200文字など)を返すように動作を変更したいのですが、理想的にはロジックを追加できるようにしたいのですが、 200 文字の後の最初の文の終わり):

class ArticleSerializer(serializers.HyperlinkedModelSerializer):
    user = UserSerializer(many=False, read_only=True)

    class Meta:
        model = models.Article
        fields = (
            'id'
            ,'title'
            , 'date_added'
            , 'content'
            , 'user'
        )

オーバーライドするものがあるかもしれないと思った GenericAPIView を見ました - しかし、何も明白に見えません - 誰かが洞察を与えることができますか? 前もって感謝します

4

2 に答える 2

5

それがあなたが必要としているものだと確信しています:

http://django-rest-framework.org/api-guide/fields.html#serializermethodfield

class ArticleSerializer(serializers.HyperlinkedModelSerializer):
    user = UserSerializer(many=False, read_only=True)
    teaser = serializers.SerializerMethodField('get_teaser')

    class Meta:
        model = models.Article
        fields = (
            'id'
            ,'title'
            , 'date_added'
            , 'user'
            , 'teaser'
        )

    def get_teaser(self, obj):
        return force_text(obj.content[:20])
于 2013-10-02T19:46:57.097 に答える
2

私はmariodevの解決策を受け入れています-それは機能し、私が最初に考えていたことです。要件を拡張し、ティーザー機能を他のフィールドに適用したいので、最終的には次のようになりました。

from django import forms
from rest_framework.compat import force_text
from rest_framework import serializers, fields

class TeaserField(fields.Field):

    def __init__(self, teaser_length=None, original_field=None):
        self.teaser_length = teaser_length
        self.original_field = original_field
        super(fields.Field, self).__init__()

    def field_to_native(self, obj, field_name):
        if(self.original_field != None):
            field_name = self.original_field

        value = getattr(obj, field_name)
        return self.to_native(value)

    def to_native(self, value):
        def joinEm(chunk):
            teaser = ''
            i=0
            while len(teaser) < self.teaser_length:
                teaser += chunk[i] + '.'
                i += 1

            return teaser

        chunk = value.split('.')
        teaser = joinEm(chunk)

        strongOpenTag = '<strong>'
        strongOpen = teaser.find(strongOpenTag)
        strongClose = teaser.find('</strong>')

        if(strongOpen > 0 and strongClose < 0):
            teaser  = teaser.replace(strongOpenTag,'')

        return force_text(teaser)

以前のソリューション

これは私の現在の作業ソリューションです。これに関する意見を知りたいです。

from django import forms
from rest_framework.compat import force_text

class TeaserField(fields.CharField):
    def __init__(self, teaser_length=None, *args, **kwargs):
        self.teaser_length = teaser_length
        super(TeaserField, self).__init__(*args, **kwargs)

    def to_native(self, value):
        return force_text(value[:self.teaser_length])


class ArticleSerializer(serializers.HyperlinkedModelSerializer):
    user = UserSerializer(many=False, read_only=True)
    content = TeaserField(teaser_length=20)
    class Meta:
        model = models.Article
        fields = (
            'id'
            ,'title'
            , 'date_added'
            , 'content'
            , 'user'
        )


class IdeaSerializer(serializers.HyperlinkedModelSerializer):
    user = UserSerializer(many=False, read_only=True)
    teaser = myFields.TeaserField(teaser_length=200, original_field='content')

    class Meta:
        model = myModels.Idea
        fields = (
            'id'
            ,'title'
            , 'date_added'
            , 'user'
            , 'content'
            , 'teaser'
        )
于 2013-10-02T19:42:10.020 に答える