<s> from copy import deepcopy <EOL> from django . core . exceptions import ValidationError <EOL> class Factory ( object ) : <EOL> """<STR_LIT>""" <EOL> missing = ( None , ) <EOL> prevent_extra_fields = True <EOL> spec = None <EOL> default_create_values = { } <EOL> def __init__ ( <EOL> self , <EOL> klass = None , <EOL> spec = None , <EOL> prevent_extra_fields = None ) : <EOL> """<STR_LIT>""" <EOL> if klass : <EOL> self . klass = klass <EOL> if spec : <EOL> self . spec = spec <EOL> if prevent_extra_fields is not None : <EOL> self . prevent_extra_fields = prevent_extra_fields <EOL> if self . spec : <EOL> self . property_name_map = self . _create_mappings ( self . spec ) <EOL> def create ( self , data ) : <EOL> """<STR_LIT>""" <EOL> if data is None : <EOL> return None <EOL> prototype = { } <EOL> errors = { } <EOL> for field_name , field_spec in self . spec . fields . items ( ) : <EOL> try : <EOL> value = self . _create_value ( data , field_name , self . spec ) <EOL> except ValidationError , e : <EOL> if field_name not in self . default_create_values : <EOL> if hasattr ( e , '<STR_LIT>' ) : <EOL> errors . update ( dict ( zip ( <EOL> [ field_name + '<STR_LIT:.>' + key for key in e . message_dict . keys ( ) ] , <EOL> e . message_dict . values ( ) ) ) ) <EOL> else : <EOL> errors [ field_name ] = e . messages <EOL> else : <EOL> key_name = self . property_name_map [ field_name ] <EOL> prototype [ key_name ] = value <EOL> if self . prevent_extra_fields : <EOL> extras = set ( data . keys ( ) ) - set ( self . property_name_map . keys ( ) ) <EOL> if extras : <EOL> errors [ '<STR_LIT:U+002CU+0020>' . join ( extras ) ] = [ '<STR_LIT>' ] <EOL> if errors : <EOL> raise ValidationError ( errors ) <EOL> _data = deepcopy ( self . default_create_values ) <EOL> _data . update ( prototype ) <EOL> if self . klass : <EOL> instance = self . klass ( ) <EOL> instance . __dict__ . update ( prototype ) <EOL> return instance <EOL> else : <EOL> return prototype <EOL> def serialize ( self , entity , request = None ) : <EOL> """<STR_LIT>""" <EOL> def should_we_insert ( value , field_spec ) : <EOL> return value not in self . missing or field_spec . required <EOL> errors = { } <EOL> ret = { } <EOL> for field_name , field_spec in self . spec . fields . items ( ) : <EOL> value = self . _get_value_for_serialization ( entity , field_name , field_spec ) <EOL> func = self . _get_serialize_func ( field_name , self . spec ) <EOL> try : <EOL> value = func ( value , entity , request ) <EOL> if should_we_insert ( value , field_spec ) : <EOL> ret [ field_name ] = value <EOL> except ValidationError , e : <EOL> if hasattr ( e , '<STR_LIT>' ) : <EOL> errors . update ( dict ( zip ( <EOL> [ field_name + '<STR_LIT:.>' + key for key in e . message_dict . keys ( ) ] , <EOL> e . message_dict . values ( ) ) ) ) <EOL> else : <EOL> errors [ field_name ] = e . messages <EOL> if errors : <EOL> raise ValidationError ( errors ) <EOL> return None if ret == { } else ret <EOL> def _create_value ( self , data , name , spec ) : <EOL> """<STR_LIT>""" <EOL> field = getattr ( self , '<STR_LIT>' + name , None ) <EOL> if field : <EOL> return field ( data , name , spec ) <EOL> value = data . get ( name ) <EOL> return spec . fields [ name ] . clean ( value ) <EOL> def _get_serialize_func ( self , name , spec ) : <EOL> """<STR_LIT>""" <EOL> func = getattr ( self , '<STR_LIT>' + name , None ) <EOL> if func : <EOL> return func <EOL> func = getattr ( spec . fields [ name ] , '<STR_LIT>' , None ) <EOL> if func : <EOL> return func <EOL> return lambda value , entity , request : value <EOL> def _get_value_for_serialization ( self , data , name , spec ) : <EOL> """<STR_LIT>""" <EOL> name = self . property_name_map [ name ] <EOL> return getattr ( data , name , None ) <EOL> def _create_mappings ( self , spec ) : <EOL> """<STR_LIT>""" <EOL> ret = dict ( zip ( set ( spec . fields ) , set ( spec . fields ) ) ) <EOL> ret . update ( dict ( [ ( n , s . alias ) for n , s in spec . fields . items ( ) if s . alias ] ) ) <EOL> return ret </s>
