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.
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")
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)
queryset_response
. Wenn Sie queryset_response = True
setzen, lautet die Antwort queryset (bis jetzt handelt es sich um ein Array von queryset. Ich persönlich denke, es wäre einfacher zu verwenden, wenn es queryset wäre).Recommended Posts