当前位置: 首页 > 编程笔记 >

django-rest-framework 加快序列化程序查询

艾哲
2023-03-14
本文向大家介绍django-rest-framework 加快序列化程序查询,包括了django-rest-framework 加快序列化程序查询的使用技巧和注意事项,需要的朋友参考一下

示例

假设我们有Travel很多相关领域的模型

class Travel(models.Model):

    tags = models.ManyToManyField(
        Tag,
        related_name='travels', )
    route_places = models.ManyToManyField(
        RoutePlace,
        related_name='travels', )
    coordinate = models.ForeignKey(
        Coordinate,
        related_name='travels', )
    date_start = models.DateField()

我们想/travels通过ViewViewSet构建CRUD 。
这是简单的视图集:

class TravelViewset(viewsets.ModelViewSet):

    queryset = Travel.objects.all()
    serializer_class = TravelSerializer

该ViewSet的问题在于我们的Travel模型中有许多相关字段,因此Django将为每个Travel实例命中db 。我们可以称之为select_related并直接prefetch_relatedqueryset属性,但如果我们想单独为串行什么list,retrieve,create...视图集中行动。
因此,我们可以将此逻辑放入一个mixin并从中继承:

class QuerySerializerMixin(object):
    PREFETCH_FIELDS = [] # Here is for M2M fields
    RELATED_FIELDS = [] # Here is for ForeignKeys

    @classmethod
    def get_related_queries(cls, queryset):
        # This method we will use in our ViewSet
        # for modify queryset, based on RELATED_FIELDS and PREFETCH_FIELDS
        if cls.RELATED_FIELDS:
            queryset = queryset.select_related(*cls.RELATED_FIELDS)
        if cls.PREFETCH_FIELDS:
            queryset = queryset.prefetch_related(*cls.PREFETCH_FIELDS) 
        return queryset


    class TravelListSerializer(QuerySerializerMixin, serializers.ModelSerializer):
    
        PREFETCH_FIELDS = ['tags'']
        RELATED_FIELDS = ['coordinate']
        # I omit fields and Meta declare for this example


    class TravelRetrieveSerializer(QuerySerializerMixin, serializers.ModelSerializer):
    
        PREFETCH_FIELDS = ['tags', 'route_places']

现在ViewSet用新的序列化器重写我们的

class TravelViewset(viewsets.ModelViewSet):

    queryset = Travel.objects.all()
        
    def get_serializer_class():
        ifself.action== 'retrieve':
            return TravelRetrieveSerializer
        elifself.action== 'list':
            return TravelListSerializer
        else:
            return SomeDefaultSerializer

        
    def get_queryset(self):
        # This method return serializer class
        # which we pass in class method of serializer class
        # which is also return by get_serializer()
        q = super(TravelViewset, self).get_queryset()
        serializer = self.get_serializer()
        return serializer.get_related_queries(q)
           

 类似资料:
  • 问题内容: 情况 在Django REST Framework的验证中工作时,我注意到字段总是被验证,即使这样做不一定有意义。以以下示例进行模型的序列化: 我有一个创建用户的端点。因此,有一个领域和一个领域。如果两个字段不匹配,则无法创建用户。同样,如果所请求的已经存在,则无法创建用户。 用户为上述每个字段发布了不正确的值 已在序列化程序中实现的实现(请参见下文),以捕获不匹配和字段 实施: 问题

  • 问题内容: 我有一个具有可选字段的对象。我以这种方式定义了我的序列化器: 我认为 如果不存在,可以绕过该字段。但是,在文档中提到这会影响反序列化而不是序列化。 我收到以下错误: 当我尝试访问序列化实例时,这正在发生。(这是否意味着反序列化导致了这一问题?) 对于没有的实例会发生这种情况。如果我从序列化程序类中忽略它,则可以正常工作。 如何正确执行此操作?即,使用可选字段序列化对象。 问题答案: 序

  • 问题内容: 我正在使用django rest框架来创建API。我有以下型号: 为类别创建序列化器: …这将为我提供: 我将如何从Item序列化程序获得相反的结果,即: 我已经阅读了有关其余框架的反向关系的文档,但这似乎与非反向字段的结果相同。我是否缺少明显的东西? 问题答案: 只需使用相关字段而不进行设置。 请注意,这也是因为你想要将输出命名为,而实际字段是,因此需要source在序列化程序字段上

  • 问题内容: 我已经尝试过类似的方法,但是它不起作用。 我需要一种能够从我的Serializer类访问request.user的方法。 问题答案: 你不能直接访问。你需要访问请求对象,然后获取用户属性。 像这样: 为了更安全,

  • 问题内容: 我正在编写一个食谱管理器作为课程的示例项目。除了使用一些非常基本的功能之外,我对DRF并没有太多的经验。目的是: 创建具有相关成分的新配方。在创建配方对象的同时创建成分对象。 models.py: serializers.py 这样可以在数据库中成功创建配方对象和配料对象,但不会将配料列表与配方相关联。我认为这是因为运行时字典中的成分被删除了,所以当我使用创建新的配方时,没有相关的成分

  • 问题内容: 该场景非常简单: 我有一个带有某些必填字段的模型。假设其中一个是不能的。我也有一个代表该模型的(Django Rest Framework)。 当使用空字符串通过序列化程序设置该字段时,返回的错误来自模型本身()。 我想仅在序列化程序级别覆盖错误消息,而无需显式重新指定序列化程序中的每个字段(我认为这违反了DRY原理),而必须为每个字段编写一个方法并引发自己的问题ValidationE