首页 > 解决方案 > 如何从反向外键 Django 序列化程序(一对多)中获取所有相关对象?

问题描述

我一直在尝试创建一个类似 Trello 的克隆,并将我的“列表”和“应用程序”存储为单独的模型,并在“应用程序”模型上使用外键创建列表和应用程序之间的一对多。我通常使用 Node 和 Sequelize 并且尝试查询我的列表并返回所有具有列表 ID 作为应用程序外键的应用程序都失败了。我怀疑我只是在我的序列化器上遗漏了一些愚蠢的东西。

我已经尝试了一些破坏代码的方法,但现在我只是让它返回列表的字段,如下所示:

[
    {
        "title": "My First List"
    }, 
    {
        "title": "My Second List"
    }, 
] 

实际上,我真正想要的是:

[
    {       "id": 1,
            "title": "My First List",
                "applications": [
                        {
                            "id": 1,
                            "company_name": "Spotify",
                            "position": "Web Engineer",
                            "date_applied": "2019-09-09",
                            "application_id": "xv112_cv",
                            "priority_level": "High",
                            "company_contact_email": "jg@spotify.com",
                            "notes": "Seems promising",
                            "location": "New York",
                            "status_list": "1"
                    },
                    {
                            "id": "2",
                            "company_name": "Foursquare",
                            "position": "Client Solutions Engineer",
                            "date_applied": "2019-10-09",
                            "application_id": "fsq_app_1",
                            "priority_level": "High",
                            "company_contact_email": "jdwyer@foursquare.com",
                            "notes": "Interview on 9/29/19",
                            "location": "New York",
                            "status_list": "1"
                    },
                ]
            }, 
            {
                "id": "2"
                "title": "My Second List",
                "applications": "applications": [
                    {
                        "id": "3",
                        "company_name": "Etsy",
                        "position": "Web Engineer",
                        "date_applied": "2019-09-09",
                        "application_id": "12345",
                        "priority_level": "High",
                        "company_contact_email": "",
                        "notes": "Seems promising",
                        "location": "New York",
                        "status_list": 2
                }
            ] 
        }
]

这是我的模型:

class List(models.Model):
    title = models.CharField(max_length=100)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)


class Application(models.Model):
    _list = models.ForeignKey(
        List, related_name='list', on_delete=models.CASCADE, null=True
    )
    company_name = models.CharField(max_length=100)
    position = models.CharField(max_length=100)
    date_applied = models.DateField(
        default=date.today(), blank=True)
    application_id = models.CharField(blank=True, max_length=100)
    [ . . . ]

我的序列化器在这里:

class ListSerializer(serializers.ModelSerializer):

    applications_set = ApplicationSerializer(read_only=True, many=True)

    class Meta:
        model = List
        fields = ('title', 'applications_set',)
        depth = 1


class ApplicationSerializer(serializers.ModelSerializer):

    class Meta:
        model = Application
        fields = '__all__'

我知道我的 List 模型上没有“applications”或“applications_set”字段,但我认为由于定义了 fkey 关联,所以没有必要。

我正在尝试做的事情可能吗?我错过了什么?

我的观点也可供参考:

class AllListsViewSet(viewsets.ModelViewSet):
    queryset = List.objects.all()

    permission_classes = [permissions.AllowAny]

    serializer_class = ListSerializer

class ApplicationViewSet(viewsets.ModelViewSet):

    queryset = Application.objects.all()

    permission_classes = [
        permissions.AllowAny
    ]
    serializer_class = ApplicationSerializer

编辑: 想通了-在我的应用程序模型上,我只是对相关名称属性进行了小调整:

status_list = models.ForeignKey(
        List, related_name='applications', on_delete=models.CASCADE, null=True
    )

在我的 ListSerializer 上:

class ListSerializer(serializers.ModelSerializer):

    applications = ApplicationSerializer(read_only=True, many=True)

    class Meta:
        model = List
        fields = ('title', 'applications',)

标签: djangodjango-modelsdjango-rest-frameworkone-to-manydjango-serializer

解决方案


你已经给你的 FK 一个related_name。这会覆盖application_set. 您已将其称为它list,这根本不是一个好名称,但由于您已设置它,因此您需要将其用作序列化程序中的字段名称。

我建议删除该related_name属性 - 并重命名 FK 本身,字段名称中不应有下划线前缀。


推荐阅读