Django REST framework - Сериализатор отношений User.username - PullRequest
0 голосов
/ 18 февраля 2020

Я работаю над проектом django, и у меня есть модель, которая выглядит следующим образом:

class Comment(models.Model):
    user            = models.ForeignKey(settings.AUTH_USER_MODEL, default=1,on_delete=models.CASCADE)
    slug            = models.SlugField(unique=True,null=True, blank=True)
    content_type    = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id       = models.PositiveIntegerField()
    content_object  = GenericForeignKey('content_type', 'object_id')
    parent          = models.ForeignKey("self", null=True, blank=True,on_delete=models.CASCADE)
    content         = models.TextField()
    timestamp       = models.DateTimeField(auto_now_add=True)

    objects = CommentManager()

    def __str__(self):
        return str(self.user.username)

Я использую этот сериализатор:

class CommentDetailSerializer(ModelSerializer):
    user = SerializerMethodField()
    replies = SerializerMethodField()
    class Meta:
        model = Comment
        fields = [
            'user',
            'content',
            'replies',
            'timestamp'
        ]
    def get_user(self,obj):
        return str(obj.user.username)

    def get_replies(self,obj):
        if obj.is_parent:
            return CommentChildSerializer(obj.children(),many=True).data

для этого вида:

class CommentDetailApiView(RetrieveAPIView):
    queryset = Comment.objects.all()
    serializer_class = CommentDetailSerializer
    lookup_field = 'slug'

вот PostSerializer, который я использую,

class PostSerializer(ModelSerializer):
    user = SerializerMethodField()
    comments = SerializerMethodField()
    class Meta:
        model = Post
        fields = [
            'user',
            'title',
            'content',
            'comments'
        ]
    def get_user(self,obj):
        return str(obj.user.username)

    def get_comments(self,obj):
        comments_qs = Comment.objects.filter_by_instance(obj)
        comments = CommentSerializer(comments_qs, many=True).data
        return comments

это то, что я получаю в PostDetailAPIView:


{
    "user": "abc",
    "title": "blabla",
    "content": "bla",
    "comments": [
        {
            "user": 1,
            "content": "hey",
            "timestamp": "2020-02-18T00:07:29.932850Z"
        }
    ]
}

Как получить имя пользователя комментария вместо его идентификатора?

Я получаю имя пользователя комментария только в CommentDetailApiView.

Спасибо

Ответы [ 4 ]

0 голосов
/ 20 февраля 2020

Я добавил get_user метод к CommentSerializer, и теперь он работает:

class CommentSerializer(serializers.ModelSerializer):
    user = SerializerMethodField()
    class Meta:
        model = Comment
        fields = [
            'user',
            'content',
            'timestamp'
        ]
    def get_user(self,obj):
        return str(obj.user.username)
0 голосов
/ 18 февраля 2020

Вам необходимо переопределить функцию to_representation(), как показано ниже:

def to_representation(self, instance):
    """Convert `username` to lowercase."""
    ret = super().to_representation(instance)
    ret['username'] = ret['username'].lower()
    return ret

Приведенный выше код является лишь примером. Он вернет имя пользователя строчными буквами. В вашем случае просто измените строку

ret['username'] = ret['username'].lower()

на

ret['username'] = self.validated_data['username']

0 голосов
/ 19 февраля 2020

StringRelatedField может использоваться для представления цели отношения, используя метод __str__.

Например, следующий сериализатор.

class CommentDetailSerializer(serializers.ModelSerializer):
    user = serializers.StringRelatedField()
    ...

    class Meta:
        model = Comment
        fields = [
            'user',
            'content',
            'replies',
            'timestamp'
        ]
        ...
0 голосов
/ 18 февраля 2020

Вы можете добавить UserSerializer, чтобы указать, что вы хотите показать пользователю:

from django.contrib.auth.models import User

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('username',)

class CommentDetailSerializer(ModelSerializer):
    user = UserSerializer()
    ..... # the rest of your code
...