[PYTHON] [DRF] Snippet zur Beschleunigung von PrimaryKeyRelatedField

Einführung

Wenn Sie "PrimaryKeyRelatedField" im Serializer auf "many = True" setzen, können Sie ein Array von pk als Anforderungsparameter übergeben, aber es wird durcheinander gebracht, wenn es viel pk gibt. Deshalb habe ich die Ursache untersucht und darüber nachgedacht, wie ich sie beschleunigen kann.

Ursache

Fazit das ist

ManyRelatedField.py


def to_internal_value(self, data):
    if isinstance(data, str) or not hasattr(data, '__iter__'):
        self.fail('not_a_list', input_type=type(data).__name__)
    if not self.allow_empty and len(data) == 0:
        self.fail('empty')

    return [
        self.child_relation.to_internal_value(item)
        for item in data
    ]

Es war langsam, weil das Array "self.child_relation.to_internal_value (item)" aufgerufen wurde (pk in "to_internal_value")

Schnipsel zum Beschleunigen

from rest_framework import serializers
from rest_framework.relations import MANY_RELATION_KWARGS, ManyRelatedField


class PrimaryKeyRelatedFieldEx(serializers.PrimaryKeyRelatedField):
    def __init__(self, **kwargs):
        self.queryset_response = kwargs.pop('queryset_response', False)
        super().__init__(**kwargs)

    class _ManyRelatedFieldEx(ManyRelatedField):
        def to_internal_value(self, data):
            if isinstance(data, str) or not hasattr(data, '__iter__'):
                self.fail('not_a_list', input_type=type(data).__name__)
            if not self.allow_empty and len(data) == 0:
                self.fail('empty')
            return self.child_relation.to_internal_value(data)

    @classmethod
    def many_init(cls, *args, **kwargs):
        list_kwargs = {'child_relation': cls(*args, **kwargs)}
        for key in kwargs:
            if key in MANY_RELATION_KWARGS:
                list_kwargs[key] = kwargs[key]
        return cls._ManyRelatedFieldEx(**list_kwargs)

    def to_internal_value(self, data):
        if isinstance(data, list):
            if self.pk_field is not None:
                data = self.pk_field.to_internal_value(data)
            results = self.get_queryset().filter(pk__in=data)
            #Überprüfen Sie, ob alle Daten verfügbar sind
            pk_list = results.values_list('pk', flat=True)
            pk_list = [str(n) for n in pk_list]
            data_list = [str(n) for n in data]
            diff = list(set(data_list) - set(list(pk_list)))
            if len(diff) > 0:
                pk_value = ', '.join(map(str, diff))
                self.fail('does_not_exist', pk_value=pk_value)
            if self.queryset_response:
                return results
            else:
                return list(results)
        else:
            return super().to_internal_value(data)

Kommentar

Recommended Posts

[DRF] Snippet zur Beschleunigung von PrimaryKeyRelatedField
Numba als Python zu beschleunigen
Project Euler 4 Versuch zu beschleunigen
So beschleunigen Sie Python-Berechnungen
Wie man die schöne Suppeninstanziierung beschleunigt
Wie man Scicit-Learn wie Conda Numpy beschleunigt
[Python] Geben Sie Ihr Bestes, um SQL Alchemy zu beschleunigen
Versuch und Irrtum, um die Erzeugung von Wärmekarten zu beschleunigen
Versuch und Irrtum, um Android-Screenshots zu beschleunigen
775/664, 777/666, 755/644 usw.
Was ich getan habe, um die String-Suchaufgabe zu beschleunigen
Ich habe versucht, die Videoerstellung durch parallele Verarbeitung zu beschleunigen
Mongodb Kürzeste Einführung (3) Ich habe versucht, sogar Millionen zu beschleunigen
Beschleunigen Sie den Befehl netstat
Schreiben Sie Python nicht, wenn Sie es mit Python beschleunigen möchten
[Python] Drücken Sie Keras von TensorFlow und TensorFlow von c ++, um die Ausführung zu beschleunigen.
Unverzichtbar, wenn Sie Python verwenden! Wie man Numpy benutzt, um Berechnungen zu beschleunigen!