Недавно я пробовал что-то новое с Django, чтобы попытаться упростить написание ответов в представлениях, возможно, не стоит делать в конце, но мне все еще интересно посмотреть, можно ли это сделать.
Как правило, у нас будет следующий сериализатор для возврата обратной информации:
# serializers.py
class SomeDefinedSerializer(serializers.ModelSerializer):
extra_model = SomeExtraModelSerializer()
greet_name = serializers.SerializerMethodField()
class Meta:
model = SomeDefinedModel
fields = ('name', 'age', 'field1', 'field2')
def get_greet_name(self, obj):
return f"Hello {obj.name}"
Теперь с этим определенным сериализатором мы можем вернуть просто нужных нам полей и затем предположитьв SomeExtraModelSerializer()
мы определили подмножество полей, мы получаем хороший словарь значений с вызовом .data
.
Но, делая это с крупномасштабными приложениями, мы в конечном итоге будем писать нагрузки и нагрузкииз сериализаторов, которые просто используются для конкретных задач, в результате чего много кода, который почти виртуально похож.Конечно, мы НЕ ДОЛЖНЫ делать это таким образом, мы могли бы создавать более общие сериализаторы, но это означает, что все различные задачи из внешнего интерфейса в итоге получают огромный избыток информации, что в действительности только небольшой процент данных получаетused.
Поэтому моей первоначальной идеей было создать базовый класс сериализатора, чтобы все другие сериализаторы основывались на нем с помощью пользовательского метода <strong>init</strong>
, чтобы вы могли просто вызывать сериализатор и передавать какkwargs
поля, которые вы хотите, или исключить ...
Но потом я подумал, но таким образом мы все еще должны определить сериализаторы для определенных задач.
Как насчет того, чтобы в представлениях django я мог определить сериализатор и его вложенные сериализаторы, все со своими собственными конкретными полями, которые я хочу вернуть, на лету, что бы вроде работало как:*
Итак, я написал основной способ, как это сделать, и он действительно работает, за исключением того, что, хотя основной сериализатор возвращает нужные мне поля, вложенный сериализатор возвращает обратно список primary_keys, которые связаны с первымтаблица через внешний ключ.Очевидно, мне нужны только поля "extra_field1", "extra_field2"
, но я не могу понять, где я ошибаюсь.Код ниже:
class SingleUseSerializer():
def __init__(self, userdata, model, many=False, fields=None, exclude=None):
if not fields and not exclude:
cprint("SingleUseSerializer: fields and exclude are both None, can only have one.", "red")
if fields and exclude:
cprint("SingleUseSerializer: fields and exclude are both present, can only have one.", "red")
self.main_serializer = {
"model": model,
"many": many,
"fields": fields,
"exclude": exclude
}
self.extra_serializers = {}
self.userdata = userdata
def load_extra_serializer(self, model, return_name, many=False, fields=None, exclude=None):
self.extra_serializers[return_name] = {
"model": model,
"many": many,
"fields": fields,
"exclude": exclude
}
def checkout(self, query):
def getSerializerClass(name):
class A(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
x = kwargs.get("fields", None)
if x:
self.Meta.fields = x
self.Meta.exclude = None
del kwargs["fields"]
y = kwargs.get("exclude", None)
if y:
self.Meta.exclude = y
self.Meta.fields = None
del kwargs["exclude"]
if not x and not y:
self.Meta.exclude = ('updated', 'created',)
self.Meta.fields = None
super(A, self).__init__(*args, **kwargs)
class Meta:
model = None
return type(name, (A,), {})
main_serializer_class = getSerializerClass(name="MainSerializer")
for k, v in self.extra_serializers.items():
inner_serializer_class = getSerializerClass(name=str(k))
inner_serializer_class.Meta.model = v["model"]
inst = inner_serializer_class(many=True, fields=v["fields"])
setattr(main_serializer_class, str(k), inst)
self.main_serializer["fields"] += (str(k),)
main_serializer_class.Meta.model = self.main_serializer["model"]
x = main_serializer_class(query, context={"userdata": self.userdata}, fields=self.main_serializer["fields"])
return x.data
Таким образом, мой вопрос заключается в том, как успешно вернуть обратно только выбранные поля на вложенных сериализаторах внутри созданных на лету сериализаторов, а не только значения pk.ПРИМЕЧАНИЕ: поля выбора для основного сериализатора работают и возвращают только те, которые мне нужны ...