<s> '''<STR_LIT>''' <EOL> from django . db import models <EOL> from django . contrib . contenttypes . models import ContentType <EOL> from django . contrib . contenttypes import generic <EOL> from django . db . models import signals <EOL> from django . db . models . base import ModelBase <EOL> from expedient . common . utils . managers import GenericObjectManager <EOL> def _extendable_post_save ( sender , ** kwargs ) : <EOL> '''<STR_LIT>''' <EOL> if kwargs [ '<STR_LIT>' ] . content_object == None : <EOL> kwargs [ '<STR_LIT>' ] . content_object = kwargs [ '<STR_LIT>' ] <EOL> signals . post_save . disconnect ( _extendable_post_save , sender ) <EOL> kwargs [ '<STR_LIT>' ] . save ( ) <EOL> signals . post_save . connect ( _extendable_post_save , sender ) <EOL> class ExtendableMeta ( ModelBase ) : <EOL> '''<STR_LIT>''' <EOL> def __new__ ( cls , name , bases , attrs ) : <EOL> '''<STR_LIT>''' <EOL> class Extend : pass <EOL> extend = attrs . setdefault ( '<STR_LIT>' , Extend ) <EOL> if ( name != "<STR_LIT>" or <EOL> attrs [ '<STR_LIT>' ] != ExtendableMeta . __module__ ) : <EOL> extended_fields = { } <EOL> repl_kw = set ( ) <EOL> for base in bases : <EOL> if isinstance ( base , ExtendableMeta ) : <EOL> base_extend = getattr ( base , "<STR_LIT>" , Extend ) <EOL> for fname , fval in getattr ( base_extend , "<STR_LIT>" , { } ) . items ( ) : <EOL> field_cls , args , kwargs , args_repl , kwargs_repl = fval <EOL> if fname in extended_fields : <EOL> raise Exception ( <EOL> "<STR_LIT>" % ( fname , base ) <EOL> + "<STR_LIT>" <EOL> + "<STR_LIT>" % ( attrs [ '<STR_LIT>' ] , name ) ) <EOL> else : <EOL> clashes = set ( args_repl ) . intersection ( repl_kw ) <EOL> clashes = clashes . union ( set ( kwargs_repl . values ( ) ) . intersection ( repl_kw ) ) <EOL> if clashes : <EOL> raise Exception ( <EOL> "<STR_LIT>" % clashes <EOL> + "<STR_LIT>" % attrs [ '<STR_LIT>' ] <EOL> + "<STR_LIT>" % ( <EOL> name , base ) ) <EOL> else : <EOL> extended_fields [ fname ] = fval <EOL> delegations = getattr ( extend , "<STR_LIT>" , [ ] ) <EOL> for d in delegations : <EOL> if d not in extended_fields : <EOL> raise Exception ( <EOL> "<STR_LIT>" % d <EOL> + "<STR_LIT>" % ( <EOL> attrs [ '<STR_LIT>' ] , name ) ) <EOL> else : <EOL> extend . fields = getattr ( extend , "<STR_LIT>" , { } ) <EOL> extend . fields [ d ] = extended_fields [ d ] <EOL> del extended_fields [ d ] <EOL> if extended_fields : <EOL> repl = getattr ( extend , '<STR_LIT>' , { } ) <EOL> for fname , fval in extended_fields . items ( ) : <EOL> field_cls , args , kwargs , args_repl , kwargs_repl = fval <EOL> if args_repl : <EOL> if len ( args_repl ) != len ( args ) : <EOL> raise Exception ( "<STR_LIT>" <EOL> + "<STR_LIT>" <EOL> + "<STR_LIT>" ) <EOL> z = zip ( args , args_repl ) <EOL> args = [ repl [ t [ <NUM_LIT:1> ] ] if t [ <NUM_LIT:1> ] != None and t [ <NUM_LIT:1> ] in repl else t [ <NUM_LIT:0> ] for t in z ] <EOL> kwargs = kwargs . copy ( ) <EOL> if kwargs_repl : <EOL> for repl_arg , repl_key in kwargs_repl . items ( ) : <EOL> if repl_key in repl : <EOL> kwargs [ repl_arg ] = repl [ repl_key ] <EOL> if fname in attrs : <EOL> raise Exception ( <EOL> "<STR_LIT>" % fname <EOL> + "<STR_LIT>" % ( attrs [ '<STR_LIT>' ] , name ) ) <EOL> attrs [ fname ] = field_cls ( * args , ** kwargs ) <EOL> new_cls = super ( ExtendableMeta , cls ) . __new__ ( cls , name , bases , attrs ) <EOL> signals . post_save . connect ( _extendable_post_save , new_cls ) <EOL> return new_cls <EOL> class Extendable ( models . Model ) : <EOL> '''<STR_LIT>''' <EOL> objects = GenericObjectManager ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> content_type = models . ForeignKey ( ContentType , editable = False , <EOL> null = True , blank = True ) <EOL> object_id = models . PositiveIntegerField ( editable = False , <EOL> null = True , blank = True ) <EOL> content_object = generic . GenericForeignKey ( ) <EOL> __metaclass__ = ExtendableMeta <EOL> class Meta : <EOL> abstract = True <EOL> def as_leaf_class ( self ) : <EOL> '''<STR_LIT>''' <EOL> if not self . content_object : <EOL> self . content_object = self <EOL> self . save ( ) <EOL> return self . content_object </s>
