Django Экземпляр объекта обратной связи каркаса REST - PullRequest
0 голосов
/ 15 января 2020

Допустим, у нас есть модели, как показано ниже

class Movie(models.Model):
    """Stores a single movie entry."""

    title = models.CharField(max_length=200, blank=False)


class Watchlist(models.Model):
    """Stores a user watchlist."""

    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             related_name='watchlist',
                             on_delete=models.CASCADE)
    movie = models.ForeignKey(Movie, related_name='watchlist',
                              on_delete=models.CASCADE)
    added = models.BooleanField(default=False)

Сериализатор

class CustomUserSerializer(serializers.HyperlinkedModelSerializer):
    """Serializer for a custom user model with related user action."""

    url = serializers.HyperlinkedIdentityField(
        view_name='customuser-detail', lookup_field='username')

    watchlist = serializers.HyperlinkedRelatedField(
        many=True, view_name='watchlist-detail', read_only=True)

    class Meta:
        model = CustomUser
        fields = ('url', 'username', 'watchlist')

и вид:

class CustomUserViewSet(viewsets.ReadOnlyModelViewSet):
    """
    list:
    Return a list of all the existing users.

    retrieve:
    Return the given user with user's watchlist.  

    """

    queryset = CustomUser.objects.all()
    permissions = (IsAdminOrReadOnly)
    lookup_field = 'username'
    serializer_class = CustomUserSerializer

Это все даст нам пользователя и гиперссылки, поданные в конкретный список наблюдения.

{
    "url": "http://127.0.0.1:8000/api/v1/users/John/",
    "username": "John",
    "favorites": [
        "http://127.0.0.1:8000/api/v1/watchlist/2/",
        "http://127.0.0.1:8000/api/v1/watchlist/1/"
    ]
},

, но вместо этого я хотел бы получить конкретный экземпляр mov ie, подобный этому.

{
    "url": "http://127.0.0.1:8000/api/v1/users/John/",
    "username": "John",
    "favorites": [
        "http://127.0.0.1:8000/api/v1/movies/33/",
        "http://127.0.0.1:8000/api/v1/movies/12/"
    ]
},

, поэтому мой вопрос заключается в том, как могу ли я достичь этого? Я пробовал с гиперссылкой по связанному полю, но, похоже, ничего не работает, как ожидалось.

1 Ответ

1 голос
/ 15 января 2020

Вы можете использовать SerializerMethodField вместе с reverse .

from rest_framework.reverse import reverse

class CustomUserSerializer(serializers.HyperlinkedModelSerializer):
    """Serializer for a custom user model with related user action."""

    url = serializers.HyperlinkedIdentityField(
        view_name='customuser-detail', lookup_field='username')

    favorites = serializers.SerializerMethodField()

    def get_favorites(self, obj):
        movie_urls = [
            reverse("movie-view", args=[watchlist.movie.id], request=self.context['request'])
            for watchlist in obj.watchlist.all()
        ]
        return movie_urls

    class Meta:
        model = CustomUser
        fields = ('url', 'username', 'favorites')
...