Django Rest Framework - 自动注释查询集

时间:2018-01-08 15:44:54

标签: python django serialization django-rest-framework django-orm

我在项目的许多不同位置使用了一个Serializer。我需要使用一个注释,但问题是我不想在所有视图中对其进行注释,因此我想在Serializer本身中进行通用注释。

有可能吗?

现在我需要在每次序列化之前执行此操作:

City.objects....filter....annotate(
                number_of_users_here_now=Count('current_userprofiles'))

我试过了:

class NumberOfUsersInCityNowField(serializers.Field):
    def to_native(self, value):
        count = value.annotate(
            number_of_users_here_now=Count('current_userprofiles'))['current_userprofiles__count']
        return count


class CityMapSerializer(serializers.ModelSerializer):
    number_of_users_here_now = NumberOfUsersInCityNowField()

    class Meta:
        model = City
        fields = ('place_id', 'lat', 'lng', 'number_of_users_here_now', 'formatted_address')

Serializer返回:

  

/ api / ajax-check-trip-creation中的AttributeError Got AttributeError   尝试获取字段number_of_users_here_now的值时   序列化器CityMapSerializer。序列化程序字段可能已命名   错误且不匹配City实例上的任何属性或键。   原始例外文字是:' City'对象没有属性   ' number_of_users_here_now'

修改

class NumberOfUsersInCityNowField(serializers.PrimaryKeyRelatedField):
    def get_queryset(self):
        return City.objects.annotate(
        number_of_users_here_now=Count('current_userprofiles'))

class CityMapSerializer(serializers.ModelSerializer):
    # number_of_users_here_now = serializers.IntegerField()
    number_of_users_here_now = NumberOfUsersInCityNowField()
    class Meta:
        model = City
        fields = ('place_id', 'lat', 'lng', 'number_of_users_here_now', 'formatted_address')

但是

serializers.CityMapSerializer(City.objects.all()[:3],many=True).data

仍然会返回:

AttributeError: 'City' object has no attribute 'number_of_users_here_now'

1 个答案:

答案 0 :(得分:0)

您可以将查询集的count方法与SerializerMethodField

一起使用
class CityMapSerializer(serializers.ModelSerializer):
    number_of_users_here_now = SerializerMethodField()

    def get_number_of_users_here_now (self, obj):
        return obj.current_userprofiles.count()

<强> UPD

另外,为避免n + 1个查询,您可以尝试实施get_queryset序列化程序的NumberOfUsersInCityNowField方法:

class NumberOfUsersInCityNowField(serializers.PrimaryKeyRelatedField):
    def get_queryset(self):
        return City.objects.annotate(
        number_of_users_here_now=Count('current_userprofiles'))['current_userprofiles__count']