如何在 JSON 的 GET 请求中包含 Django 模型的外键列表?

How can I include in the JSON's GET request the list of foreign keys of a model in Django?

我的模型有可以拥有多个设备的用户。当我对用户执行 GET 请求时,它 returns 只有用户模型中指定的字段,这是应该的。但我希望该选项在 GET 请求返回的 JSON 中包含用户拥有的设备列表。我怎样才能做到这一点?其次,有没有办法有时可以让用户在相同 JSON 中获得设备列表,而其他时候却没有?另外,我真的是 Django 的新手,如果可能的话,我希望有很多代码示例可以更好地理解。

这些是我的模型:

class User(models.Model):
    name = models.CharField(max_length=100)
    birth_date = models.DateField()
    address = models.CharField(max_length=200)

class Device(models.Model):
    description = models.CharField(max_length=200)
    location = models.CharField(max_length=200)
    max_energy_consumption = models.FloatField()
    avg_energy_consuumption = models.FloatField()
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)

我的序列化程序:

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

class DeviceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Device
        fields = '__all__'

以及以下用于 CRUD api 调用的默认 ModelViewSets:

class UserViewSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer


class DeviceViewSet(ModelViewSet):
    queryset = Device.objects.all()
    serializer_class = DeviceSerializer

有一些不同的方法,最简单的方法是在您的用户模型中添加一个 property 并将其添加到您的序列化程序中

class User(models.Model):
    name = models.CharField(max_length=100)
    birth_date = models.DateField()
    address = models.CharField(max_length=200)


    @property
    def devices(self):
        return Device.objects.filter(user_id=self.id).values("location", "description").distinct()


class UserSerializer(serializers.ModelSerializer):
    devices = serializers.ReadOnlyField()
    class Meta:
        model = User
        fields = '__all__'

编辑 - 对于问题的第二部分: 我的经验是,当我们不需要所有信息(性能问题)时,在我们的序列化程序中编写 '__all__' 并不是最好的做法。为了解决这个问题,制作一个单独的序列化程序将再次成为一个简单的解决方案。每当我遇到这种事情时,我都会查询相同的端点,但会发送一个我不在其他端点中使用的不同 qs 在你的情况下,假设你的用户视图集路由类似于 /api/user/ 你可以在发送你的时添加一个 qs向您的后端发出请求并添加 ?with_devices=true。 然后你可以像这样使用你的第二个用户序列化器:

class UserViewSet(ModelViewSet):
    queryset = User.objects.all()

    def get_serializer_class(self):
        if self.request.GET.get("with_devices", False):
            return UserWithDeviceSerializer
        return UserSerializer
    

你的序列化器应该是这样的:

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["name", "birth_date", ..so on]


class UserWithDeviceSerializer(serializers.ModelSerializer):
    devices = serializers.ReadOnlyField()
    class Meta:
        model = User
        fields = '__all__'

这将为您提供您在评论中提出的问题。