2016-11-11 4 views
2

Ниже приведен мой python marshmallow сериализатор, который я использую в своем приложении на основе SQLAlchemy.Marshmallow: Как я могу переопределить этот конструктор класса python?

import simplejson 
from marshmallow import Schema 
class MySerializer(Schema): 
    class Meta: 
     json_module = simplejson 
     fields = ('field1', 'field2', 'field3') 

    field3 = fields.Method('get_field3') 

    def get_field3(self, this_obj): 
     return "Hello" 

Вот как я называю это сериалайзер:

my_argument = 1 
items=MySerializer(documents=list_of_my_objects, many=True).data 

Теперь я хочу, чтобы изменить сериалайзер таким образом, что он принимает дополнительный аргумент (я передам в my_argument) и, если значение этого аргумент равен 1, возвращает "Goodbye" вместо "Hello". Как я могу это сделать?

В частности, я не знаю, как я могу передать аргумент этой схеме Маршаллоу, чтобы он был доступен изнутри get_field3. Я знаю, что мне нужно переопределить метод __init__(). Но я не уверен, как это должно выглядеть. Я попытался следующий, но это не сработало:

def __init__(self, documents, many, my_arg): 
    self.my_arg = my_arg 
    super(Schema, self).__init__(documents, many=many) 

def get_field3(self, this_obj): 
    self.my_arg == 1: 
     return "Goodbye" 
    else: 
     return "Hello" 

Это был стек следом я получил:

my_project/my_models/serializers.pyc in __init__(self, documents, many, my_arg) 
---> 25   super(Schema, self).__init__(documents, many=many) 

my_virtualenv/lib/python2.7/site-packages/marshmallow/schema.pyc in __init__(self, obj, extra, only, exclude, prefix, strict, many, skip_missing, context) 
--> 273    self._update_fields(self.obj, many=many) 

my_virtualenv/lib/python2.7/site-packages/marshmallow/schema.pyc in _update_fields(self, obj, many) 
--> 636   ret = self.__filter_fields(field_names, obj, many=many) 

my_virtualenv/lib/python2.7/site-packages/marshmallow/schema.pyc in __filter_fields(self, field_names, obj, many) 
--> 683       attribute_type = type(obj_dict[key]) 
TypeError: list indices must be integers, not str 

ответ

1

Просто поп добавляемого ARG от kwargs, чтобы избежать каких-либо ошибок (вы можете передавать любой kwargs к методу переопределен таким образом):

class MySerializer(Schema): 
    # ... 
    def __init__(self, *args, **kwargs): 
     self.my_arg = kwargs.pop('my_arg') if 'my_arg' in kwargs else None 
     super(Schema, self).__init__(*args, **kwargs) 

Теперь вы можете передать пользовательские kwarg (ключевого слова аргумент, а не позиционный) для создания объектов:

MySerializer(documents=list_of_my_objects, many=True, my_arg=1)