如何在 Django Rest Framework 中设置嵌套的相关字段序列化程序?

How to set nested related fields serializers in Djando Rest Framework?

我正在使用 Django Rest Framework 构建一个 API,其中我有以下用户制作、确认和表现出对事件的兴趣的模型:

models.py

class User(AbstractBaseUser, PermissionsMixin):
    user_name = models.CharField(_("user name"), max_length=150, unique=True)
    slug = AutoSlugField(populate_from='user_name', unique=True)
    
class Event(models.Model):
    name = models.CharField(max_length=100, blank=False, null=False)
    owner = models.ForeignKey(User, related_name="owned_events", on_delete=models.SET_NULL, blank=True, null=True)
    confirmed = models.ManyToManyField(User, related_name="confirmed_events", blank=True)
    interested = models.ManyToManyField(User, related_name="interested_events", blank=True)

为了序列化它,我使用了我在此处和 DRF 文档中找到的以下代码:

serializers.py

class UserSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = User
        fields = [
            "url",
            "user_name",
            "password",
        ]
        extra_kwargs = { "password": {"write_only": True} }


class EventSerializer(serializers.HyperlinkedModelSerializer):
    owner = UserSerializer(required=False)
    confirmed = UserSerializer(required=False, many=True)
    interested = UserSerializer(required=False, many=True)

    class Meta:
        model = Event
        lookup_field = 'slug'
        extra_kwargs = { 'url': {'lookup_field': 'slug'} }
        fields = [
            "url",
            "owner",
            "name", 
            "confirmed",
            "interested",
        ]

它工作得很好,但我希望 UserSerializer 显示每个用户的确认和感兴趣的事件,就像每个事件显示用户确认和感兴趣的一样。我更改了序列化程序并获得了每个事件的 url,就像这样:

serializers.py 在 UserSerializer 上使用 HyperlinkedRelatedField

class UserSerializer(serializers.HyperlinkedModelSerializer):
    confirmed_events = serializers.HyperlinkedRelatedField(
        queryset=Event.objects.all(),
        view_name='event-detail', 
        lookup_field='slug', 
        many=True, 
        required=False
    )
    interested_events = serializers.HyperlinkedRelatedField(
        queryset=Event.objects.all(),
        view_name='event-detail', 
        lookup_field='slug', 
        many=True, 
        required=False
    )

    class Meta:
        model = User
        fields = [
            "url",
            "user_name",
            "password",
            "confirmed_events",
            "interested_events",
        ]
        extra_kwargs = { "password": {"write_only": True} }

这让我从用户模型中获得了以下 JSON:

 {
        "user_name": "d",
        "confirmed_events": [],
        "interested_events": [
            "http://localhost:8000/events/eqwer-2/",
            "http://localhost:8000/events/test/",
            "http://localhost:8000/events/test-2/",
            "http://localhost:8000/events/test-3/",
        ]
 }

并且来自事件模型:

{
    "url": "http://localhost:8000/events/eqwer-2/",
    "owner": null,
    "name": "eqwer",
    "slug": "eqwer-2",
    "confirmed": [],
    "interested": [
        {
            "user_name": "d",
            "confirmed_events": [],
            "interested_events": [
                "http://localhost:8000/events/eqwer-2/",
                "http://localhost:8000/events/test/",
                "http://localhost:8000/events/test-2/",
                "http://localhost:8000/events/test-3/",

            ]
        }
    ]
},

事件模型 JSON 很好,因为它显示每个用户的数据,但我希望用户 JSON 显示每个事件数据,而不仅仅是事件 URL,它' d 是这样的:

 {
        "user_name": "d",
        "confirmed_events": [],
        "interested_events": [
            {
                "url": "http://localhost:8000/events/eqwer-2/",
                "owner": null,
                "name": "eqwer",
                "slug": "eqwer-2",             
            },
        ]
 }

像这样为 interested_events 创建一个单独的序列化程序:

class InterestedEventsSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        fields = ('url', 'owner', 'name', 'slug')

并在您的 UserSerializer 中使用上面的序列化程序声明 interested_events

class UserSerializer(serializers.HyperlinkedModelSerializer):
    confirmed_events = ... #
    interested_events = InterestedEventsSerializer(many=True)

    class Meta:
        model = User
        fields = [
            "url",
            "user_name",
            "password",
            "confirmed_events",
            "interested_events",
        ]
        extra_kwargs = { "password": {"write_only": True} }