#NEWLINE# def save( self , * args , **kwargs ) : #NEWLINE# #INDENT# "\n        If this is a new node, sets tree fields up before it is inserted\n        into the database, making room in the tree structure as neccessary,\n        defaulting to making the new node the last child of its parent.\n\n        It the node's left and right edge indicators already been set, we\n        take this as indication that the node has already been set up for\n        insertion, so its tree fields are left untouched.\n\n        If this is an existing node and its parent has been changed,\n        performs reparenting in the tree structure, defaulting to making the\n        node the last child of its new parent.\n\n        In either case, if the node's class has its ``order_insertion_by``\n        tree option set, the node will be inserted or moved to the\n        appropriate position to maintain ordering by the specified field.\n        " #NEWLINE# do_updates = self . __class__ . _mptt_updates_enabled #NEWLINE# track_updates = self . __class__ . _mptt_is_tracking #NEWLINE# opts = self . _mptt_meta #NEWLINE# if ( not ( do_updates or track_updates ) ) : #NEWLINE# #INDENT# if ( self . _mpttfield ( 'left' ) is None ) : #NEWLINE# #INDENT# parent = getattr ( self , ( '_%s_cache' % opts . parent_attr ) , None ) #NEWLINE# if parent : #NEWLINE# #INDENT# left = ( parent . _mpttfield ( 'left' ) + 1 ) #NEWLINE# setattr ( self , opts . left_attr , left ) #NEWLINE# setattr ( self , opts . right_attr , ( left + 1 ) ) #NEWLINE# setattr ( self , opts . level_attr , ( parent . _mpttfield ( 'level' ) + 1 ) ) #NEWLINE# setattr ( self , opts . tree_id_attr , parent . _mpttfield ( 'tree_id' ) ) #NEWLINE# self . _tree_manager . _post_insert_update_cached_parent_right ( parent , 2 ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# setattr ( self , opts . left_attr , 1 ) #NEWLINE# setattr ( self , opts . right_attr , 2 ) #NEWLINE# setattr ( self , opts . level_attr , 0 ) #NEWLINE# setattr ( self , opts . tree_id_attr , 0 ) #NEWLINE# #UNINDENT# #UNINDENT# return super ( MPTTModel , self ) . save ( * args , ** kwargs ) #NEWLINE# #UNINDENT# parent_id = opts . get_raw_field_value ( self , opts . parent_attr ) #NEWLINE# force_update = kwargs . get ( 'force_update' , False ) #NEWLINE# force_insert = kwargs . get ( 'force_insert' , False ) #NEWLINE# collapse_old_tree = None #NEWLINE# deferred_fields = self . get_deferred_fields ( ) #NEWLINE# if ( force_update or ( ( not force_insert ) and self . _is_saved ( using = kwargs . get ( 'using' ) ) ) ) : #NEWLINE# #INDENT# old_parent_id = self . _mptt_cached_fields [ opts . parent_attr ] #NEWLINE# if ( old_parent_id is DeferredAttribute ) : #NEWLINE# #INDENT# same_order = True #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# same_order = ( old_parent_id == parent_id ) #NEWLINE# #UNINDENT# if ( same_order and ( len ( self . _mptt_cached_fields ) > 1 ) ) : #NEWLINE# #INDENT# for ( field_name , old_value ) in self . _mptt_cached_fields . items ( ) : #NEWLINE# #INDENT# if ( ( old_value is DeferredAttribute ) and ( field_name not in deferred_fields ) ) : #NEWLINE# #INDENT# same_order = False #NEWLINE# break #NEWLINE# #UNINDENT# if ( old_value != opts . get_raw_field_value ( self , field_name ) ) : #NEWLINE# #INDENT# same_order = False #NEWLINE# break #NEWLINE# #UNINDENT# #UNINDENT# if ( ( not do_updates ) and ( not same_order ) ) : #NEWLINE# #INDENT# same_order = True #NEWLINE# self . __class__ . _mptt_track_tree_modified ( self . _mpttfield ( 'tree_id' ) ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( ( not do_updates ) and ( not same_order ) and ( old_parent_id is None ) ) : #NEWLINE# #INDENT# collapse_old_tree = self . _mpttfield ( 'tree_id' ) #NEWLINE# parent = getattr ( self , opts . parent_attr ) #NEWLINE# tree_id = parent . _mpttfield ( 'tree_id' ) #NEWLINE# left = ( parent . _mpttfield ( 'left' ) + 1 ) #NEWLINE# self . __class__ . _mptt_track_tree_modified ( tree_id ) #NEWLINE# setattr ( self , opts . tree_id_attr , tree_id ) #NEWLINE# setattr ( self , opts . left_attr , left ) #NEWLINE# setattr ( self , opts . right_attr , ( left + 1 ) ) #NEWLINE# setattr ( self , opts . level_attr , ( parent . _mpttfield ( 'level' ) + 1 ) ) #NEWLINE# same_order = True #NEWLINE# #UNINDENT# #UNINDENT# if ( not same_order ) : #NEWLINE# #INDENT# opts . set_raw_field_value ( self , opts . parent_attr , old_parent_id ) #NEWLINE# try : #NEWLINE# #INDENT# right_sibling = None #NEWLINE# if opts . order_insertion_by : #NEWLINE# #INDENT# right_sibling = opts . get_ordered_insertion_target ( self , getattr ( self , opts . parent_attr ) ) #NEWLINE# #UNINDENT# if ( parent_id is not None ) : #NEWLINE# #INDENT# parent = getattr ( self , opts . parent_attr ) #NEWLINE# update_cached_parent = ( ( getattr ( self , opts . tree_id_attr ) != getattr ( parent , opts . tree_id_attr ) ) or ( getattr ( self , opts . left_attr ) < getattr ( parent , opts . left_attr ) ) or ( getattr ( self , opts . right_attr ) > getattr ( parent , opts . right_attr ) ) ) #NEWLINE# #UNINDENT# if right_sibling : #NEWLINE# #INDENT# self . _tree_manager . _move_node ( self , right_sibling , 'left' , save = False , refresh_target = False ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( parent_id is None ) : #NEWLINE# #INDENT# root_nodes = self . _tree_manager . root_nodes ( ) #NEWLINE# try : #NEWLINE# #INDENT# rightmost_sibling = root_nodes . exclude ( pk = self . pk ) . order_by ( ( '-' + opts . tree_id_attr ) ) [ 0 ] #NEWLINE# self . _tree_manager . _move_node ( self , rightmost_sibling , 'right' , save = False , refresh_target = False ) #NEWLINE# #UNINDENT# except IndexError : #NEWLINE# #INDENT# pass #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# self . _tree_manager . _move_node ( self , parent , 'last-child' , save = False ) #NEWLINE# #UNINDENT# #UNINDENT# if ( ( parent_id is not None ) and update_cached_parent ) : #NEWLINE# #INDENT# right_shift = ( 2 * ( self . get_descendant_count ( ) + 1 ) ) #NEWLINE# self . _tree_manager . _post_insert_update_cached_parent_right ( parent , right_shift ) #NEWLINE# #UNINDENT# #UNINDENT# finally : #NEWLINE# #INDENT# opts . set_raw_field_value ( self , opts . parent_attr , parent_id ) #NEWLINE# #UNINDENT# node_moved . send ( sender = self . __class__ , instance = self , target = getattr ( self , opts . parent_attr ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# opts . set_raw_field_value ( self , opts . parent_attr , parent_id ) #NEWLINE# if ( not track_updates ) : #NEWLINE# #INDENT# if ( len ( args ) > 3 ) : #NEWLINE# #INDENT# if ( not args [ 3 ] ) : #NEWLINE# #INDENT# args = list ( args ) #NEWLINE# args [ 3 ] = self . _get_user_field_names ( ) #NEWLINE# args = tuple ( args ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( not kwargs . get ( 'update_fields' , None ) ) : #NEWLINE# #INDENT# kwargs [ 'update_fields' ] = self . _get_user_field_names ( ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( getattr ( self , opts . left_attr ) and getattr ( self , opts . right_attr ) ) : #NEWLINE# #INDENT# pass #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# parent = getattr ( self , opts . parent_attr ) #NEWLINE# right_sibling = None #NEWLINE# if ( do_updates or ( parent is None ) ) : #NEWLINE# #INDENT# if opts . order_insertion_by : #NEWLINE# #INDENT# right_sibling = opts . get_ordered_insertion_target ( self , parent ) #NEWLINE# #UNINDENT# #UNINDENT# if right_sibling : #NEWLINE# #INDENT# self . insert_at ( right_sibling , 'left' , allow_existing_pk = True , refresh_target = False ) #NEWLINE# if parent : #NEWLINE# #INDENT# right_shift = ( 2 * ( self . get_descendant_count ( ) + 1 ) ) #NEWLINE# self . _tree_manager . _post_insert_update_cached_parent_right ( parent , right_shift ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# self . insert_at ( parent , position = 'last-child' , allow_existing_pk = True ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# try : #NEWLINE# #INDENT# super ( MPTTModel , self ) . save ( * args , ** kwargs ) #NEWLINE# #UNINDENT# finally : #NEWLINE# #INDENT# if ( collapse_old_tree is not None ) : #NEWLINE# #INDENT# self . _tree_manager . _create_tree_space ( collapse_old_tree , ( - 1 ) ) #NEWLINE# #UNINDENT# #UNINDENT# self . _mptt_saved = True #NEWLINE# opts . update_mptt_cached_fields ( self )