В сериализаторе Django, как мне сериализовать обе стороны отношения внешнего ключа? - PullRequest
0 голосов
/ 07 ноября 2018

В моем коде Django у меня есть эта модель:

class Swipe(models.Model):
    user = models.ForeignKey(
        Profile,
        related_name='swipes',
        on_delete=models.CASCADE,
        null=False,
        default=None
    )

    SWIPE_CHOICES = (
        (1, "left"),
        (2, "right"),
        (3, "up"),
        (4, "down")
    )

    direction = models.IntegerField(
        choices = SWIPE_CHOICES
    )

, где Профиль - мой класс пользователя. У меня есть вид для отображения всех профилей:

class ProfileList(generics.ListCreateAPIView):
    serializer_class = ProfileSerializer
    queryset = Profile.objects.all()

    def perform_create(self, serializer):
        serializer.save()

где ProfileSerializer выглядит так:

class ProfileSerializer(serializers.HyperlinkedModelSerializer):

    # serializations of other fields

    class Meta:
        model = Profile
        fields = (
            'url', 'id', 'username', 'password',
            'first_name', 'last_name', 'email',
            'swipes',
        )

Эта сериализация моего класса Profile возвращает только URL для «swipes» (например, «[host] / swipe / 1»).

Я знаю, что это противоположно тому, как должны работать отношения с внешним ключом, но есть ли способ для меня сериализовать эту информацию о пальце, чтобы показать, например, направление свипа, а не просто URL-адрес для сам размах?

При сериализации Swipe, я могу заставить сериализацию связанного профиля работать, добавив "user = ProfileSerializer ()". Однако, когда я пытаюсь добавить «swipes = SwipeSerializer ()» в мой код, поле swipes переходит от отображения списка URL-адресов к пустой карте («{}»).

Это проблема с тем фактом, что я «переворачиваю» отношения с внешним ключом? Как я могу заставить эту сериализацию работать?

1 Ответ

0 голосов
/ 07 ноября 2018

Вам необходимо переопределить сериализацию по умолчанию для поля swipes в ProfileSerializer. Однако вы должны быть осторожны, чтобы в указанном сериализаторе не было поля для user, которое в конечном итоге будет рекурсивно сериализировать друг друга.

В основном вам нужно что-то вроде:

class PureSwipeSerializer(serializers.HyperlinkedModelSerializer):
    ...


class PureProfileSerializer(serializers.HyperlinkedModelSerializer):
    ...

class ProfileSerializer(serializers.HyperlinkedModelSerializer):
    swipes = PureSwipeSerializer(many=True)
    ...

class SwipeSerializer(serializers.HyperlinkedModelSerializer):
    profile = PureProfileSerializer(many=False)
    ...
...