<s> """<STR_LIT>""" <EOL> from django . utils . datastructures import SortedDict <EOL> from django . forms . util import ErrorList <EOL> from django . forms . forms import BaseForm , get_declared_fields , ValidationError <EOL> from django . forms . widgets import media_property <EOL> from dockit . schema . exceptions import DotPathNotFound <EOL> import inspect <EOL> def document_to_dict ( document , instance , properties = None , exclude = None , dotpath = None ) : <EOL> """<STR_LIT>""" <EOL> data = { } <EOL> if dotpath : <EOL> try : <EOL> src_data = instance . dot_notation ( dotpath ) <EOL> except DotPathNotFound : <EOL> src_data = dict ( ) <EOL> else : <EOL> src_data = instance <EOL> if src_data is None : <EOL> src_data = dict ( ) <EOL> for prop_name in src_data . keys ( ) : <EOL> if properties and not prop_name in properties : <EOL> continue <EOL> if exclude and prop_name in exclude : <EOL> continue <EOL> if prop_name in document . _meta . fields : <EOL> prop = document . _meta . fields [ prop_name ] <EOL> if not properties and not prop . editable : <EOL> continue <EOL> data [ prop_name ] = src_data [ prop_name ] <EOL> return data <EOL> def fields_for_document ( document , properties = None , exclude = None , formfield_callback = None , dotpath = None ) : <EOL> """<STR_LIT>""" <EOL> if dotpath : <EOL> field = document . _meta . dot_notation_to_field ( dotpath ) <EOL> fields = field . schema . _meta . fields <EOL> else : <EOL> fields = document . _meta . fields <EOL> field_list = [ ] <EOL> values = [ ] <EOL> if properties : <EOL> values = [ fields [ prop ] for prop in properties if prop in fields ] <EOL> else : <EOL> values = fields . values ( ) <EOL> for prop in values : <EOL> if properties and not prop . name in properties : <EOL> continue <EOL> if exclude and prop . name in exclude : <EOL> continue <EOL> if not properties and not prop . editable : <EOL> continue <EOL> field = prop . formfield ( ) <EOL> if field and formfield_callback : <EOL> defaults = prop . formfield_kwargs ( ) <EOL> field = formfield_callback ( prop , type ( field ) , ** defaults ) <EOL> if field : <EOL> field_list . append ( ( prop . name , field ) ) <EOL> return SortedDict ( field_list ) <EOL> class DocumentFormOptions ( object ) : <EOL> def __init__ ( self , options = None ) : <EOL> self . document = getattr ( options , '<STR_LIT>' , None ) <EOL> self . schema = getattr ( options , '<STR_LIT>' , None ) <EOL> self . properties = getattr ( options , '<STR_LIT>' , None ) <EOL> self . exclude = getattr ( options , '<STR_LIT>' , None ) <EOL> self . formfield_callback = getattr ( options , '<STR_LIT>' , None ) <EOL> self . dotpath = getattr ( options , '<STR_LIT>' , None ) <EOL> if self . document and not self . schema : <EOL> if self . dotpath : <EOL> field = self . document . _meta . dot_notation_to_field ( self . dotpath ) <EOL> if hasattr ( field , '<STR_LIT>' ) : <EOL> self . schema = field . schema <EOL> else : <EOL> self . schema = self . document <EOL> class DocumentFormMetaClass ( type ) : <EOL> def __new__ ( cls , name , bases , attrs ) : <EOL> try : <EOL> parents = [ b for b in bases if issubclass ( b , DocumentForm ) ] <EOL> except NameError : <EOL> parents = None <EOL> declared_fields = get_declared_fields ( bases , attrs , False ) <EOL> new_class = super ( DocumentFormMetaClass , cls ) . __new__ ( cls , name , bases , <EOL> attrs ) <EOL> if not parents : <EOL> return new_class <EOL> if '<STR_LIT>' not in attrs : <EOL> new_class . media = media_property ( new_class ) <EOL> opts = new_class . _meta = DocumentFormOptions ( getattr ( new_class , <EOL> '<STR_LIT:Meta>' , None ) ) <EOL> if opts . schema : <EOL> fields = fields_for_document ( opts . schema , opts . properties , <EOL> opts . exclude , formfield_callback = opts . formfield_callback , ) <EOL> new_class . serialized_fields = fields . keys ( ) <EOL> fields . update ( declared_fields ) <EOL> elif opts . document : <EOL> fields = fields_for_document ( opts . document , opts . properties , <EOL> opts . exclude , formfield_callback = opts . formfield_callback , <EOL> dotpath = opts . dotpath ) <EOL> new_class . serialized_fields = fields . keys ( ) <EOL> fields . update ( declared_fields ) <EOL> else : <EOL> fields = declared_fields <EOL> new_class . declared_fields = declared_fields <EOL> new_class . base_fields = fields <EOL> return new_class <EOL> class BaseDocumentForm ( BaseForm ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , data = None , files = None , auto_id = '<STR_LIT>' , prefix = None , <EOL> initial = None , error_class = ErrorList , label_suffix = "<STR_LIT::>" , <EOL> empty_permitted = False , instance = None , dotpath = None ) : <EOL> opts = self . _meta <EOL> self . dotpath = dotpath or opts . dotpath <EOL> if instance is None : <EOL> self . instance = opts . document ( ) <EOL> object_data = { } <EOL> else : <EOL> self . instance = instance <EOL> object_data = document_to_dict ( self . _meta . document , instance , opts . properties , <EOL> opts . exclude , dotpath = self . dotpath ) <EOL> if initial is not None : <EOL> object_data . update ( initial ) <EOL> super ( BaseDocumentForm , self ) . __init__ ( data , files , auto_id , prefix , <EOL> object_data , error_class , <EOL> label_suffix , empty_permitted ) <EOL> def _clean_fields ( self ) : <EOL> for name , field in self . fields . items ( ) : <EOL> value = field . widget . value_from_datadict ( self . data , self . files , self . add_prefix ( name ) ) <EOL> try : <EOL> arg_spec = inspect . getargspec ( field . clean ) <EOL> if ( ( hasattr ( arg_spec , '<STR_LIT:args>' ) and len ( arg_spec . args ) > <NUM_LIT:2> ) or <EOL> len ( arg_spec [ <NUM_LIT:0> ] ) > <NUM_LIT:2> ) : <EOL> initial = self . initial . get ( name , field . initial ) <EOL> if callable ( initial ) : <EOL> initial = initial ( ) <EOL> value = field . clean ( value , initial ) <EOL> else : <EOL> value = field . clean ( value ) <EOL> self . cleaned_data [ name ] = value <EOL> if hasattr ( self , '<STR_LIT>' % name ) : <EOL> value = getattr ( self , '<STR_LIT>' % name ) ( ) <EOL> self . cleaned_data [ name ] = value <EOL> except ValidationError , e : <EOL> self . _errors [ name ] = self . error_class ( e . messages ) <EOL> if name in self . cleaned_data : <EOL> del self . cleaned_data [ name ] <EOL> def _inner_save ( self , dynamic = True ) : <EOL> opts = self . _meta <EOL> cleaned_data = self . cleaned_data . copy ( ) <EOL> if self . dotpath : <EOL> obj = None <EOL> try : <EOL> obj = self . instance . dot_notation ( self . dotpath ) <EOL> except : <EOL> pass <EOL> if obj is None : <EOL> obj = opts . schema ( ) <EOL> else : <EOL> data = self . instance . to_primitive ( self . instance , generate_natural_key = False ) <EOL> obj = opts . schema . to_python ( data ) <EOL> for prop_name in self . serialized_fields : <EOL> if prop_name in cleaned_data . keys ( ) : <EOL> value = cleaned_data . pop ( prop_name ) <EOL> obj [ prop_name ] = value <EOL> if dynamic : <EOL> for attr_name in cleaned_data . iterkeys ( ) : <EOL> if opts . exclude and attr_name in opts . exclude : <EOL> continue <EOL> value = cleaned_data [ attr_name ] <EOL> if value is not None : <EOL> obj [ attr_name ] = value <EOL> return obj <EOL> def save ( self , commit = True , dynamic = True ) : <EOL> """<STR_LIT>""" <EOL> self . target_object = self . _inner_save ( dynamic ) <EOL> if self . dotpath : <EOL> self . instance . dot_notation_set_value ( self . dotpath , self . target_object ) <EOL> else : <EOL> self . instance = self . target_object <EOL> data = self . instance . to_primitive ( self . instance ) <EOL> self . instance = self . _meta . document . to_python ( data ) <EOL> if commit : <EOL> self . instance . save ( ) <EOL> return self . instance <EOL> class DocumentForm ( BaseDocumentForm ) : <EOL> """<STR_LIT>""" <EOL> __metaclass__ = DocumentFormMetaClass <EOL> class UserMeta ( object ) : <EOL> def __init__ ( self , ** kwargs ) : <EOL> for key , value in kwargs . iteritems ( ) : <EOL> setattr ( self , key , value ) <EOL> def documentform_factory ( document , form = DocumentForm , fields = None , exclude = None , <EOL> formfield_callback = None , schema = None , dotpath = None ) : <EOL> meta = UserMeta ( document = document , <EOL> fields = fields , <EOL> exclude = exclude , <EOL> formfield_callback = formfield_callback , <EOL> schema = schema , <EOL> dotpath = dotpath , ) <EOL> class FactoryForm ( form ) : <EOL> Meta = meta <EOL> return FactoryForm </s>
