django rest框架使用ModelSerializer和ModelViewSet返回自定义对象

时间:2017-08-10 14:34:24

标签: django django-rest-framework

我有三个模型,三个序列化器,下面是一个模型集。 我正在使用django-rest-framework为android制作一个rest api。

首先创建了餐厅模型。然后我创建了一个星模型和一个图像模型。

我想要做的是将星形和图像对象添加到餐馆对象中。

最后我得到了我想要的结果,但我认为我的viewset代码看起来不对..

还有另一种方法是不使用" for loop"?

模型

class Restaurant(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)
    address = models.CharField(max_length=255)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    weather = models.ForeignKey(Weather, on_delete=models.CASCADE)
    distance = models.ForeignKey(Distance, on_delete=models.CASCADE)
    description = models.TextField('DESCRIPTION')

    def __str__(self):
        return self.name

class Star(models.Model):
    restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    rating = models.IntegerField('RATING')

    def __str__(self):
        return self.restaurant


class RestaurantImage(models.Model):
    id = models.AutoField(primary_key=True)
    restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
    path = models.CharField(max_length=255)

串行

class StarSerializer(serializers.ModelSerializer):
    class Meta:
        model = Star
        fields = ('id', 'restaurant', 'user', 'rating', )


class RestaurantDetailSerializer(serializers.ModelSerializer):
    category = CategorySerializer()
    weather = WeatherSerializer()
    distance = DistanceSerializer()

    class Meta:
        model = Restaurant
        fields = ('id', 'name', 'address', 'category', 'weather',
                  'distance', 'description', )


class ImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = RestaurantImage
        fields = ('id', 'path', 'restaurant')

视图集

class RestaurantDetailInfoViewSet(viewsets.ModelViewSet):
    queryset = Restaurant.objects.all()
    serializer_class = RestaurantSerializer

    def list(self, request, *args, **kwargs):
        restaurant_list = Restaurant.objects.all()
        restaurant_result = []
        for restaurant in restaurant_list:
            restaurantInfo = Restaurant.objects.filter(id=restaurant.pk)
            restaurant_serializer = RestaurantDetailSerializer(restaurantInfo, many=True)
            ratingAverageValue = Star.objects.filter(restaurant=restaurant.pk).aggregate(Avg('rating'))
            images = RestaurantImage.objects.filter(restaurant=restaurant.pk)
            image_serializer = ImageSerializer(images, many=True)

            restaurant_dic = {
                'restaurant': restaurant_serializer.data,
                'ratingAverage': ratingAverageValue['rating__avg']
                if ratingAverageValue['rating__avg'] is not None else 0,
                'images': image_serializer.data
            }
            restaurant_result.append(restaurant_dic)

        return Response(restaurant_result)

结果

[
{
    "restaurant": [
        {
            "id": 1,
            "name": "restaurant1",
            "address": "address1",
            "category": {
                "c_id": 1,
                "name": "foodtype1"
            },
            "weather": {
                "w_id": 1,
                "name": "sunny"
            },
            "distance": {
                "d_id": 1,
                "name": "inside"
            },
            "description": "description1"
        }
    ],
    "ratingAverage": 2.6667,
    "images": [
        {
            "id": 1,
            "path": "imagepath",
            "restaurant": 1
        }
    ]
},

1 个答案:

答案 0 :(得分:2)

解决方案

ImageSerializer

解释

在这里,我已经嵌套了RestaurantSerializer课程中的ImageSerializer,因为您需要在ratingAverage中定义的所有字段。
然后,对于get_ratingAverage,我使用SerializerMethodField返回我为其定义的方法中计算的值(您的逻辑),即Restaurant,它取{ {1}}实例引用作为参数传递给字段的方法。