Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Django Rest框架序列化相关pivot模型_Django_Django Rest Framework - Fatal编程技术网

使用Django Rest框架序列化相关pivot模型

使用Django Rest框架序列化相关pivot模型,django,django-rest-framework,Django,Django Rest Framework,我正在学习Django,正在使用Django Rest框架。在我的应用程序中,我有三种不同的模型 酒吧(保存关于酒吧的信息,通过BarBeer模型有多瓶啤酒) 啤酒(保存有关啤酒的信息) BarBeer(酒吧和啤酒之间的连接,有枢轴字段,如酒精、类型、价格和数量) 这就是不同模型的定义方式: class Bar(models.Model): name = models.CharField(max_length=60) location = models.PointField(

我正在学习Django,正在使用Django Rest框架。在我的应用程序中,我有三种不同的模型

  • 酒吧(保存关于酒吧的信息,通过BarBeer模型有多瓶啤酒)
  • 啤酒(保存有关啤酒的信息)
  • BarBeer(酒吧和啤酒之间的连接,有枢轴字段,如酒精、类型、价格和数量)
这就是不同模型的定义方式:

class Bar(models.Model):
    name = models.CharField(max_length=60)
    location = models.PointField()
    address = models.CharField(max_length=60)
    description = models.TextField(default='')

    beers = models.ManyToManyField('api.Beer', through='api.BarBeer')

class Beer(models.Model):
    name = models.CharField(max_length=60)
    alcohol = models.FloatField(default=0)

class BarBeer(models.Model):
    bar = models.ForeignKey(Bar, on_delete=models.CASCADE)
    beer = models.ForeignKey(Beer, on_delete=models.CASCADE)

    price = models.FloatField(default=0)
    type = EnumField(Type, default=Type.Cask)
    volume = models.IntegerField(default=0)
现在,我想序列化一个给定的酒吧,其中包含该酒吧的所有啤酒,包括pivot model
BarBeer
中的额外字段。例如,下面是我希望输出的内容(注意啤酒上额外的三个字段,来自BarBeer模型):

我不知道如何从pivot模型中获取额外字段作为序列化输出的一部分。这就是我的序列化程序现在的样子:

class BarDetailsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Bar
        fields = ('id', 'name', 'beers')
        depth = 3

一种方法是,您可以为BarBeer模型创建自定义序列化程序,并在其中传递其他两个模型序列化程序,如下所示:~

class BarDetailsSerializer(serializers.Serializer):
    bar = BarSerializer()
    beer = BeerSerializer()
    price = serializers.FloatField(required=True)
    type = serializers.CharField(required=True)
    volume = serializers.IntegerField(required=True)
只需将BarBeer对象传递给此序列化程序,它将返回所有数据点,即使是通过外键连接的对象


与您在问题中提到的回答完全相同,实现这一点的另一种方法是为您的api创建一个渲染器,并相应地对其中的数据进行格式化和结构化。

首先
beers=models.ManyToManyField('api.Beer',through='api.BarBeer')
此字段是不必要的,因为您已经创建了一个名为
BarBeer
的表。ManyToManyField意味着添加exra表格。因此,如果我们假设此字段不存在,并且您有
BarBeer表
,则可以使用
BarBeer序列化程序
这样做:

序列化程序.py

class BarBeerSerializer(serializers.ModelSerializer):
    name = serializers.SerializerMethodField()
    alchol = serializers.SerializerMethodField()

    class Meta:
        model = BarBeer
        fields = ['id','name','alchol','type','price','volume']

    def get_name(self,obj):
        return obj.beer.name

    def get_alchol(self,obj):
       return obj.beer.alchol


class BarSerializer(serializers.ModelSerializer):
    beers = serializers.SerializerMethodField()
    class Meta:
        model = Bar
        fields = ['id', 'name', 'beers']

    def get_beers(self,obj:Bar):
        beers = obj.barbeer_set.all()
        return BarBeerSerializer(beers,many=True).data
如果有错误,请在评论中询问

class BarBeerSerializer(serializers.ModelSerializer):
    name = serializers.SerializerMethodField()
    alchol = serializers.SerializerMethodField()

    class Meta:
        model = BarBeer
        fields = ['id','name','alchol','type','price','volume']

    def get_name(self,obj):
        return obj.beer.name

    def get_alchol(self,obj):
       return obj.beer.alchol


class BarSerializer(serializers.ModelSerializer):
    beers = serializers.SerializerMethodField()
    class Meta:
        model = Bar
        fields = ['id', 'name', 'beers']

    def get_beers(self,obj:Bar):
        beers = obj.barbeer_set.all()
        return BarBeerSerializer(beers,many=True).data