首页 > 解决方案 > Django:序列化器+查询优化

问题描述

我有 Django 模型,如下所示,

class Chef(models.Model):
    name = models.CharField(max_length=128, unique=True)

class Restaurant(models.Model):
    chef = models.OneToOneField(User, related_name='profile', on_delete=models.CASCADE)
    location = models.CharField(max_length=128)
    ranking = models.IntegerField(default=99999)

和序列化程序类。

class ChefSerializer(serializers.ModelSerializer):
    restaurant = RestaurantSerializer(read_only=True)
    class Meta:
        model = Chef
        fields = ('name', 'restaurant')

class RestaurantSerializer(serializers.ModelSerializer):
    class Meta:
        model = Restaurant
        fields = ('chef', 'location', 'ranking')

我用这样的。

class MyView(generics.ListCreateAPIView):
    queryset = Chef.objects.all()
    serializer_class = ChefSerializer
    ...
    def do_somthing(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset)
        calculate_something(serializer.data)
...

我想优化我的查询,所以尝试像下面这样检查它们。

...
print(queryset.query) # "SELECT chef.id, chef.name FROM chef"
...

但我找不到我RestaurantSerializer使用的确切查询。

  1. 我想做类似的事情print(restaurantserializer.data.query)。我应该怎么办?我想知道何时以及如何Restaurant执行与表相关的查询。

  2. 我还想将我的查询优化为一个查询,例如select c.name, r.location, r.ranking FROM chef c JOIN restaurant r ON c.id=r.chef_id

标签: django-rest-framework

解决方案


您可以调整查询集:

res = Restaurant.objects.only('location', 'ranking').filter(chef_id=1)

如果您想获取厨师的姓名,您必须执行以下操作:

res = Restaurant.objects.select_related('chef').only('location', 'ranking', 'chef__name').filter(chef_id=1)

您可以在django websiteselect_related中阅读更多详细信息。prefetch_related

Silk是查看 SQL 查询的一个有用的包。


推荐阅读