<s> from __future__ import unicode_literals <EOL> import datetime <EOL> import functools <EOL> import re <EOL> from itertools import chain <EOL> from django . conf import settings <EOL> from django . db import models <EOL> from django . db . migrations import operations <EOL> from django . db . migrations . migration import Migration <EOL> from django . db . migrations . operations . models import AlterModelOptions <EOL> from django . db . migrations . optimizer import MigrationOptimizer <EOL> from django . db . migrations . questioner import MigrationQuestioner <EOL> from django . db . migrations . utils import COMPILED_REGEX_TYPE , RegexObject <EOL> from django . utils import six <EOL> from . topological_sort import stable_topological_sort <EOL> class MigrationAutodetector ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , from_state , to_state , questioner = None ) : <EOL> self . from_state = from_state <EOL> self . to_state = to_state <EOL> self . questioner = questioner or MigrationQuestioner ( ) <EOL> self . existing_apps = { app for app , model in from_state . models } <EOL> def changes ( self , graph , trim_to_apps = None , convert_apps = None , migration_name = None ) : <EOL> """<STR_LIT>""" <EOL> changes = self . _detect_changes ( convert_apps , graph ) <EOL> changes = self . arrange_for_graph ( changes , graph , migration_name ) <EOL> if trim_to_apps : <EOL> changes = self . _trim_to_apps ( changes , trim_to_apps ) <EOL> return changes <EOL> def deep_deconstruct ( self , obj ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( obj , list ) : <EOL> return [ self . deep_deconstruct ( value ) for value in obj ] <EOL> elif isinstance ( obj , tuple ) : <EOL> return tuple ( self . deep_deconstruct ( value ) for value in obj ) <EOL> elif isinstance ( obj , dict ) : <EOL> return { <EOL> key : self . deep_deconstruct ( value ) <EOL> for key , value in obj . items ( ) <EOL> } <EOL> elif isinstance ( obj , functools . partial ) : <EOL> return ( obj . func , self . deep_deconstruct ( obj . args ) , self . deep_deconstruct ( obj . keywords ) ) <EOL> elif isinstance ( obj , COMPILED_REGEX_TYPE ) : <EOL> return RegexObject ( obj ) <EOL> elif isinstance ( obj , type ) : <EOL> return obj <EOL> elif hasattr ( obj , '<STR_LIT>' ) : <EOL> deconstructed = obj . deconstruct ( ) <EOL> if isinstance ( obj , models . Field ) : <EOL> deconstructed = deconstructed [ <NUM_LIT:1> : ] <EOL> path , args , kwargs = deconstructed <EOL> return ( <EOL> path , <EOL> [ self . deep_deconstruct ( value ) for value in args ] , <EOL> { <EOL> key : self . deep_deconstruct ( value ) <EOL> for key , value in kwargs . items ( ) <EOL> } , <EOL> ) <EOL> else : <EOL> return obj <EOL> def only_relation_agnostic_fields ( self , fields ) : <EOL> """<STR_LIT>""" <EOL> fields_def = [ ] <EOL> for name , field in sorted ( fields ) : <EOL> deconstruction = self . deep_deconstruct ( field ) <EOL> if field . remote_field and field . remote_field . model : <EOL> del deconstruction [ <NUM_LIT:2> ] [ '<STR_LIT:to>' ] <EOL> fields_def . append ( deconstruction ) <EOL> return fields_def <EOL> def _detect_changes ( self , convert_apps = None , graph = None ) : <EOL> """<STR_LIT>""" <EOL> self . generated_operations = { } <EOL> self . old_apps = self . from_state . concrete_apps <EOL> self . new_apps = self . to_state . apps <EOL> self . old_model_keys = [ ] <EOL> self . old_proxy_keys = [ ] <EOL> self . old_unmanaged_keys = [ ] <EOL> self . new_model_keys = [ ] <EOL> self . new_proxy_keys = [ ] <EOL> self . new_unmanaged_keys = [ ] <EOL> for al , mn in sorted ( self . from_state . models . keys ( ) ) : <EOL> model = self . old_apps . get_model ( al , mn ) <EOL> if not model . _meta . managed : <EOL> self . old_unmanaged_keys . append ( ( al , mn ) ) <EOL> elif al not in self . from_state . real_apps : <EOL> if model . _meta . proxy : <EOL> self . old_proxy_keys . append ( ( al , mn ) ) <EOL> else : <EOL> self . old_model_keys . append ( ( al , mn ) ) <EOL> for al , mn in sorted ( self . to_state . models . keys ( ) ) : <EOL> model = self . new_apps . get_model ( al , mn ) <EOL> if not model . _meta . managed : <EOL> self . new_unmanaged_keys . append ( ( al , mn ) ) <EOL> elif ( <EOL> al not in self . from_state . real_apps or <EOL> ( convert_apps and al in convert_apps ) <EOL> ) : <EOL> if model . _meta . proxy : <EOL> self . new_proxy_keys . append ( ( al , mn ) ) <EOL> else : <EOL> self . new_model_keys . append ( ( al , mn ) ) <EOL> self . generate_renamed_models ( ) <EOL> self . _prepare_field_lists ( ) <EOL> self . _generate_through_model_map ( ) <EOL> self . generate_deleted_models ( ) <EOL> self . generate_created_models ( ) <EOL> self . generate_deleted_proxies ( ) <EOL> self . generate_created_proxies ( ) <EOL> self . generate_altered_options ( ) <EOL> self . generate_altered_managers ( ) <EOL> self . generate_renamed_fields ( ) <EOL> self . generate_removed_fields ( ) <EOL> self . generate_added_fields ( ) <EOL> self . generate_altered_fields ( ) <EOL> self . generate_altered_unique_together ( ) <EOL> self . generate_altered_index_together ( ) <EOL> self . generate_altered_db_table ( ) <EOL> self . generate_altered_order_with_respect_to ( ) <EOL> self . _sort_migrations ( ) <EOL> self . _build_migration_list ( graph ) <EOL> self . _optimize_migrations ( ) <EOL> return self . migrations <EOL> def _prepare_field_lists ( self ) : <EOL> """<STR_LIT>""" <EOL> self . kept_model_keys = set ( self . old_model_keys ) . intersection ( self . new_model_keys ) <EOL> self . kept_proxy_keys = set ( self . old_proxy_keys ) . intersection ( self . new_proxy_keys ) <EOL> self . kept_unmanaged_keys = set ( self . old_unmanaged_keys ) . intersection ( self . new_unmanaged_keys ) <EOL> self . through_users = { } <EOL> self . old_field_keys = set ( ) <EOL> self . new_field_keys = set ( ) <EOL> for app_label , model_name in sorted ( self . kept_model_keys ) : <EOL> old_model_name = self . renamed_models . get ( ( app_label , model_name ) , model_name ) <EOL> old_model_state = self . from_state . models [ app_label , old_model_name ] <EOL> new_model_state = self . to_state . models [ app_label , model_name ] <EOL> self . old_field_keys . update ( ( app_label , model_name , x ) for x , y in old_model_state . fields ) <EOL> self . new_field_keys . update ( ( app_label , model_name , x ) for x , y in new_model_state . fields ) <EOL> def _generate_through_model_map ( self ) : <EOL> """<STR_LIT>""" <EOL> for app_label , model_name in sorted ( self . old_model_keys ) : <EOL> old_model_name = self . renamed_models . get ( ( app_label , model_name ) , model_name ) <EOL> old_model_state = self . from_state . models [ app_label , old_model_name ] <EOL> for field_name , field in old_model_state . fields : <EOL> old_field = self . old_apps . get_model ( app_label , old_model_name ) . _meta . get_field ( field_name ) <EOL> if ( hasattr ( old_field , "<STR_LIT>" ) and getattr ( old_field . remote_field , "<STR_LIT>" , None ) and <EOL> not old_field . remote_field . through . _meta . auto_created ) : <EOL> through_key = ( <EOL> old_field . remote_field . through . _meta . app_label , <EOL> old_field . remote_field . through . _meta . model_name , <EOL> ) <EOL> self . through_users [ through_key ] = ( app_label , old_model_name , field_name ) <EOL> def _build_migration_list ( self , graph = None ) : <EOL> """<STR_LIT>""" <EOL> self . migrations = { } <EOL> num_ops = sum ( len ( x ) for x in self . generated_operations . values ( ) ) <EOL> chop_mode = False <EOL> while num_ops : <EOL> for app_label in sorted ( self . generated_operations . keys ( ) ) : <EOL> chopped = [ ] <EOL> dependencies = set ( ) <EOL> for operation in list ( self . generated_operations [ app_label ] ) : <EOL> deps_satisfied = True <EOL> operation_dependencies = set ( ) <EOL> for dep in operation . _auto_deps : <EOL> is_swappable_dep = False <EOL> if dep [ <NUM_LIT:0> ] == "<STR_LIT>" : <EOL> resolved_app_label , resolved_object_name = getattr ( settings , dep [ <NUM_LIT:1> ] ) . split ( '<STR_LIT:.>' ) <EOL> original_dep = dep <EOL> dep = ( resolved_app_label , resolved_object_name . lower ( ) , dep [ <NUM_LIT:2> ] , dep [ <NUM_LIT:3> ] ) <EOL> is_swappable_dep = True <EOL> if dep [ <NUM_LIT:0> ] != app_label and dep [ <NUM_LIT:0> ] != "<STR_LIT>" : <EOL> for other_operation in self . generated_operations . get ( dep [ <NUM_LIT:0> ] , [ ] ) : <EOL> if self . check_dependency ( other_operation , dep ) : <EOL> deps_satisfied = False <EOL> break <EOL> if not deps_satisfied : <EOL> break <EOL> else : <EOL> if is_swappable_dep : <EOL> operation_dependencies . add ( ( original_dep [ <NUM_LIT:0> ] , original_dep [ <NUM_LIT:1> ] ) ) <EOL> elif dep [ <NUM_LIT:0> ] in self . migrations : <EOL> operation_dependencies . add ( ( dep [ <NUM_LIT:0> ] , self . migrations [ dep [ <NUM_LIT:0> ] ] [ - <NUM_LIT:1> ] . name ) ) <EOL> else : <EOL> if chop_mode : <EOL> if graph and graph . leaf_nodes ( dep [ <NUM_LIT:0> ] ) : <EOL> operation_dependencies . add ( graph . leaf_nodes ( dep [ <NUM_LIT:0> ] ) [ <NUM_LIT:0> ] ) <EOL> else : <EOL> operation_dependencies . add ( ( dep [ <NUM_LIT:0> ] , "<STR_LIT>" ) ) <EOL> else : <EOL> deps_satisfied = False <EOL> if deps_satisfied : <EOL> chopped . append ( operation ) <EOL> dependencies . update ( operation_dependencies ) <EOL> self . generated_operations [ app_label ] = self . generated_operations [ app_label ] [ <NUM_LIT:1> : ] <EOL> else : <EOL> break <EOL> if dependencies or chopped : <EOL> if not self . generated_operations [ app_label ] or chop_mode : <EOL> subclass = type ( str ( "<STR_LIT>" ) , ( Migration , ) , { "<STR_LIT>" : [ ] , "<STR_LIT>" : [ ] } ) <EOL> instance = subclass ( "<STR_LIT>" % ( len ( self . migrations . get ( app_label , [ ] ) ) + <NUM_LIT:1> ) , app_label ) <EOL> instance . dependencies = list ( dependencies ) <EOL> instance . operations = chopped <EOL> instance . initial = app_label not in self . existing_apps <EOL> self . migrations . setdefault ( app_label , [ ] ) . append ( instance ) <EOL> chop_mode = False <EOL> else : <EOL> self . generated_operations [ app_label ] = chopped + self . generated_operations [ app_label ] <EOL> new_num_ops = sum ( len ( x ) for x in self . generated_operations . values ( ) ) <EOL> if new_num_ops == num_ops : <EOL> if not chop_mode : <EOL> chop_mode = True <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" % self . generated_operations ) <EOL> num_ops = new_num_ops <EOL> def _sort_migrations ( self ) : <EOL> """<STR_LIT>""" <EOL> for app_label , ops in sorted ( self . generated_operations . items ( ) ) : <EOL> dependency_graph = { op : set ( ) for op in ops } <EOL> for op in ops : <EOL> for dep in op . _auto_deps : <EOL> if dep [ <NUM_LIT:0> ] == app_label : <EOL> for op2 in ops : <EOL> if self . check_dependency ( op2 , dep ) : <EOL> dependency_graph [ op ] . add ( op2 ) <EOL> self . generated_operations [ app_label ] = stable_topological_sort ( ops , dependency_graph ) <EOL> def _optimize_migrations ( self ) : <EOL> for app_label , migrations in self . migrations . items ( ) : <EOL> for m1 , m2 in zip ( migrations , migrations [ <NUM_LIT:1> : ] ) : <EOL> m2 . dependencies . append ( ( app_label , m1 . name ) ) <EOL> for app_label , migrations in self . migrations . items ( ) : <EOL> for migration in migrations : <EOL> migration . dependencies = list ( set ( migration . dependencies ) ) <EOL> for app_label , migrations in self . migrations . items ( ) : <EOL> for migration in migrations : <EOL> migration . operations = MigrationOptimizer ( ) . optimize ( migration . operations , app_label = app_label ) <EOL> def check_dependency ( self , operation , dependency ) : <EOL> """<STR_LIT>""" <EOL> if dependency [ <NUM_LIT:2> ] is None and dependency [ <NUM_LIT:3> ] is True : <EOL> return ( <EOL> isinstance ( operation , operations . CreateModel ) and <EOL> operation . name_lower == dependency [ <NUM_LIT:1> ] . lower ( ) <EOL> ) <EOL> elif dependency [ <NUM_LIT:2> ] is not None and dependency [ <NUM_LIT:3> ] is True : <EOL> return ( <EOL> ( <EOL> isinstance ( operation , operations . CreateModel ) and <EOL> operation . name_lower == dependency [ <NUM_LIT:1> ] . lower ( ) and <EOL> any ( dependency [ <NUM_LIT:2> ] == x for x , y in operation . fields ) <EOL> ) or <EOL> ( <EOL> isinstance ( operation , operations . AddField ) and <EOL> operation . model_name_lower == dependency [ <NUM_LIT:1> ] . lower ( ) and <EOL> operation . name_lower == dependency [ <NUM_LIT:2> ] . lower ( ) <EOL> ) <EOL> ) <EOL> elif dependency [ <NUM_LIT:2> ] is not None and dependency [ <NUM_LIT:3> ] is False : <EOL> return ( <EOL> isinstance ( operation , operations . RemoveField ) and <EOL> operation . model_name_lower == dependency [ <NUM_LIT:1> ] . lower ( ) and <EOL> operation . name_lower == dependency [ <NUM_LIT:2> ] . lower ( ) <EOL> ) <EOL> elif dependency [ <NUM_LIT:2> ] is None and dependency [ <NUM_LIT:3> ] is False : <EOL> return ( <EOL> isinstance ( operation , operations . DeleteModel ) and <EOL> operation . name_lower == dependency [ <NUM_LIT:1> ] . lower ( ) <EOL> ) <EOL> elif dependency [ <NUM_LIT:2> ] is not None and dependency [ <NUM_LIT:3> ] == "<STR_LIT>" : <EOL> return ( <EOL> isinstance ( operation , operations . AlterField ) and <EOL> operation . model_name_lower == dependency [ <NUM_LIT:1> ] . lower ( ) and <EOL> operation . name_lower == dependency [ <NUM_LIT:2> ] . lower ( ) <EOL> ) <EOL> elif dependency [ <NUM_LIT:2> ] is not None and dependency [ <NUM_LIT:3> ] == "<STR_LIT>" : <EOL> return ( <EOL> isinstance ( operation , operations . AlterOrderWithRespectTo ) and <EOL> operation . name_lower == dependency [ <NUM_LIT:1> ] . lower ( ) and <EOL> ( operation . order_with_respect_to or "<STR_LIT>" ) . lower ( ) != dependency [ <NUM_LIT:2> ] . lower ( ) <EOL> ) <EOL> elif dependency [ <NUM_LIT:2> ] is not None and dependency [ <NUM_LIT:3> ] == "<STR_LIT>" : <EOL> return ( <EOL> isinstance ( operation , ( operations . AlterUniqueTogether , <EOL> operations . AlterIndexTogether ) ) and <EOL> operation . name_lower == dependency [ <NUM_LIT:1> ] . lower ( ) <EOL> ) <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" % ( dependency , ) ) <EOL> def add_operation ( self , app_label , operation , dependencies = None , beginning = False ) : <EOL> operation . _auto_deps = dependencies or [ ] <EOL> if beginning : <EOL> self . generated_operations . setdefault ( app_label , [ ] ) . insert ( <NUM_LIT:0> , operation ) <EOL> else : <EOL> self . generated_operations . setdefault ( app_label , [ ] ) . append ( operation ) <EOL> def swappable_first_key ( self , item ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> model = self . new_apps . get_model ( item [ <NUM_LIT:0> ] , item [ <NUM_LIT:1> ] ) <EOL> base_names = [ base . __name__ for base in model . __bases__ ] <EOL> string_version = "<STR_LIT>" % ( item [ <NUM_LIT:0> ] , item [ <NUM_LIT:1> ] ) <EOL> if ( <EOL> model . _meta . swappable or <EOL> "<STR_LIT>" in base_names or <EOL> "<STR_LIT>" in base_names or <EOL> settings . AUTH_USER_MODEL . lower ( ) == string_version . lower ( ) <EOL> ) : <EOL> return ( "<STR_LIT>" + item [ <NUM_LIT:0> ] , "<STR_LIT>" + item [ <NUM_LIT:1> ] ) <EOL> except LookupError : <EOL> pass <EOL> return item <EOL> def generate_renamed_models ( self ) : <EOL> """<STR_LIT>""" <EOL> self . renamed_models = { } <EOL> self . renamed_models_rel = { } <EOL> added_models = set ( self . new_model_keys ) - set ( self . old_model_keys ) <EOL> for app_label , model_name in sorted ( added_models ) : <EOL> model_state = self . to_state . models [ app_label , model_name ] <EOL> model_fields_def = self . only_relation_agnostic_fields ( model_state . fields ) <EOL> removed_models = set ( self . old_model_keys ) - set ( self . new_model_keys ) <EOL> for rem_app_label , rem_model_name in removed_models : <EOL> if rem_app_label == app_label : <EOL> rem_model_state = self . from_state . models [ rem_app_label , rem_model_name ] <EOL> rem_model_fields_def = self . only_relation_agnostic_fields ( rem_model_state . fields ) <EOL> if model_fields_def == rem_model_fields_def : <EOL> if self . questioner . ask_rename_model ( rem_model_state , model_state ) : <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . RenameModel ( <EOL> old_name = rem_model_state . name , <EOL> new_name = model_state . name , <EOL> ) <EOL> ) <EOL> self . renamed_models [ app_label , model_name ] = rem_model_name <EOL> renamed_models_rel_key = '<STR_LIT>' % ( rem_model_state . app_label , rem_model_state . name ) <EOL> self . renamed_models_rel [ renamed_models_rel_key ] = '<STR_LIT>' % ( <EOL> model_state . app_label , <EOL> model_state . name , <EOL> ) <EOL> self . old_model_keys . remove ( ( rem_app_label , rem_model_name ) ) <EOL> self . old_model_keys . append ( ( app_label , model_name ) ) <EOL> break <EOL> def generate_created_models ( self ) : <EOL> """<STR_LIT>""" <EOL> old_keys = set ( self . old_model_keys ) . union ( self . old_unmanaged_keys ) <EOL> added_models = set ( self . new_model_keys ) - old_keys <EOL> added_unmanaged_models = set ( self . new_unmanaged_keys ) - old_keys <EOL> all_added_models = chain ( <EOL> sorted ( added_models , key = self . swappable_first_key , reverse = True ) , <EOL> sorted ( added_unmanaged_models , key = self . swappable_first_key , reverse = True ) <EOL> ) <EOL> for app_label , model_name in all_added_models : <EOL> model_state = self . to_state . models [ app_label , model_name ] <EOL> model_opts = self . new_apps . get_model ( app_label , model_name ) . _meta <EOL> related_fields = { } <EOL> primary_key_rel = None <EOL> for field in model_opts . local_fields : <EOL> if field . remote_field : <EOL> if field . remote_field . model : <EOL> if field . primary_key : <EOL> primary_key_rel = field . remote_field . model <EOL> elif not field . remote_field . parent_link : <EOL> related_fields [ field . name ] = field <EOL> if ( getattr ( field . remote_field , "<STR_LIT>" , None ) and <EOL> not field . remote_field . through . _meta . auto_created ) : <EOL> related_fields [ field . name ] = field <EOL> for field in model_opts . local_many_to_many : <EOL> if field . remote_field . model : <EOL> related_fields [ field . name ] = field <EOL> if getattr ( field . remote_field , "<STR_LIT>" , None ) and not field . remote_field . through . _meta . auto_created : <EOL> related_fields [ field . name ] = field <EOL> unique_together = model_state . options . pop ( '<STR_LIT>' , None ) <EOL> index_together = model_state . options . pop ( '<STR_LIT>' , None ) <EOL> order_with_respect_to = model_state . options . pop ( '<STR_LIT>' , None ) <EOL> dependencies = [ <EOL> ( app_label , model_name , None , False ) , <EOL> ] <EOL> for base in model_state . bases : <EOL> if isinstance ( base , six . string_types ) and "<STR_LIT:.>" in base : <EOL> base_app_label , base_name = base . split ( "<STR_LIT:.>" , <NUM_LIT:1> ) <EOL> dependencies . append ( ( base_app_label , base_name , None , True ) ) <EOL> if primary_key_rel : <EOL> dependencies . append ( ( <EOL> primary_key_rel . _meta . app_label , <EOL> primary_key_rel . _meta . object_name , <EOL> None , <EOL> True <EOL> ) ) <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . CreateModel ( <EOL> name = model_state . name , <EOL> fields = [ d for d in model_state . fields if d [ <NUM_LIT:0> ] not in related_fields ] , <EOL> options = model_state . options , <EOL> bases = model_state . bases , <EOL> managers = model_state . managers , <EOL> ) , <EOL> dependencies = dependencies , <EOL> beginning = True , <EOL> ) <EOL> if not model_opts . managed : <EOL> continue <EOL> for name , field in sorted ( related_fields . items ( ) ) : <EOL> dependencies = self . _get_dependecies_for_foreign_key ( field ) <EOL> dependencies . append ( ( app_label , model_name , None , True ) ) <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . AddField ( <EOL> model_name = model_name , <EOL> name = name , <EOL> field = field , <EOL> ) , <EOL> dependencies = list ( set ( dependencies ) ) , <EOL> ) <EOL> related_dependencies = [ <EOL> ( app_label , model_name , name , True ) <EOL> for name , field in sorted ( related_fields . items ( ) ) <EOL> ] <EOL> related_dependencies . append ( ( app_label , model_name , None , True ) ) <EOL> if unique_together : <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . AlterUniqueTogether ( <EOL> name = model_name , <EOL> unique_together = unique_together , <EOL> ) , <EOL> dependencies = related_dependencies <EOL> ) <EOL> if index_together : <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . AlterIndexTogether ( <EOL> name = model_name , <EOL> index_together = index_together , <EOL> ) , <EOL> dependencies = related_dependencies <EOL> ) <EOL> if order_with_respect_to : <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . AlterOrderWithRespectTo ( <EOL> name = model_name , <EOL> order_with_respect_to = order_with_respect_to , <EOL> ) , <EOL> dependencies = [ <EOL> ( app_label , model_name , order_with_respect_to , True ) , <EOL> ( app_label , model_name , None , True ) , <EOL> ] <EOL> ) <EOL> def generate_created_proxies ( self ) : <EOL> """<STR_LIT>""" <EOL> added = set ( self . new_proxy_keys ) - set ( self . old_proxy_keys ) <EOL> for app_label , model_name in sorted ( added ) : <EOL> model_state = self . to_state . models [ app_label , model_name ] <EOL> assert model_state . options . get ( "<STR_LIT>" ) <EOL> dependencies = [ <EOL> ( app_label , model_name , None , False ) , <EOL> ] <EOL> for base in model_state . bases : <EOL> if isinstance ( base , six . string_types ) and "<STR_LIT:.>" in base : <EOL> base_app_label , base_name = base . split ( "<STR_LIT:.>" , <NUM_LIT:1> ) <EOL> dependencies . append ( ( base_app_label , base_name , None , True ) ) <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . CreateModel ( <EOL> name = model_state . name , <EOL> fields = [ ] , <EOL> options = model_state . options , <EOL> bases = model_state . bases , <EOL> managers = model_state . managers , <EOL> ) , <EOL> dependencies = dependencies , <EOL> ) <EOL> def generate_deleted_models ( self ) : <EOL> """<STR_LIT>""" <EOL> new_keys = set ( self . new_model_keys ) . union ( self . new_unmanaged_keys ) <EOL> deleted_models = set ( self . old_model_keys ) - new_keys <EOL> deleted_unmanaged_models = set ( self . old_unmanaged_keys ) - new_keys <EOL> all_deleted_models = chain ( sorted ( deleted_models ) , sorted ( deleted_unmanaged_models ) ) <EOL> for app_label , model_name in all_deleted_models : <EOL> model_state = self . from_state . models [ app_label , model_name ] <EOL> model = self . old_apps . get_model ( app_label , model_name ) <EOL> if not model . _meta . managed : <EOL> continue <EOL> related_fields = { } <EOL> for field in model . _meta . local_fields : <EOL> if field . remote_field : <EOL> if field . remote_field . model : <EOL> related_fields [ field . name ] = field <EOL> if ( getattr ( field . remote_field , "<STR_LIT>" , None ) and <EOL> not field . remote_field . through . _meta . auto_created ) : <EOL> related_fields [ field . name ] = field <EOL> for field in model . _meta . local_many_to_many : <EOL> if field . remote_field . model : <EOL> related_fields [ field . name ] = field <EOL> if getattr ( field . remote_field , "<STR_LIT>" , None ) and not field . remote_field . through . _meta . auto_created : <EOL> related_fields [ field . name ] = field <EOL> unique_together = model_state . options . pop ( '<STR_LIT>' , None ) <EOL> index_together = model_state . options . pop ( '<STR_LIT>' , None ) <EOL> if unique_together : <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . AlterUniqueTogether ( <EOL> name = model_name , <EOL> unique_together = None , <EOL> ) <EOL> ) <EOL> if index_together : <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . AlterIndexTogether ( <EOL> name = model_name , <EOL> index_together = None , <EOL> ) <EOL> ) <EOL> for name , field in sorted ( related_fields . items ( ) ) : <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . RemoveField ( <EOL> model_name = model_name , <EOL> name = name , <EOL> ) <EOL> ) <EOL> dependencies = [ ] <EOL> for related_object in model . _meta . related_objects : <EOL> related_object_app_label = related_object . related_model . _meta . app_label <EOL> object_name = related_object . related_model . _meta . object_name <EOL> field_name = related_object . field . name <EOL> dependencies . append ( ( related_object_app_label , object_name , field_name , False ) ) <EOL> if not related_object . many_to_many : <EOL> dependencies . append ( ( related_object_app_label , object_name , field_name , "<STR_LIT>" ) ) <EOL> for name , field in sorted ( related_fields . items ( ) ) : <EOL> dependencies . append ( ( app_label , model_name , name , False ) ) <EOL> through_user = self . through_users . get ( ( app_label , model_state . name_lower ) ) <EOL> if through_user : <EOL> dependencies . append ( ( through_user [ <NUM_LIT:0> ] , through_user [ <NUM_LIT:1> ] , through_user [ <NUM_LIT:2> ] , False ) ) <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . DeleteModel ( <EOL> name = model_state . name , <EOL> ) , <EOL> dependencies = list ( set ( dependencies ) ) , <EOL> ) <EOL> def generate_deleted_proxies ( self ) : <EOL> """<STR_LIT>""" <EOL> deleted = set ( self . old_proxy_keys ) - set ( self . new_proxy_keys ) <EOL> for app_label , model_name in sorted ( deleted ) : <EOL> model_state = self . from_state . models [ app_label , model_name ] <EOL> assert model_state . options . get ( "<STR_LIT>" ) <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . DeleteModel ( <EOL> name = model_state . name , <EOL> ) , <EOL> ) <EOL> def generate_renamed_fields ( self ) : <EOL> """<STR_LIT>""" <EOL> self . renamed_fields = { } <EOL> for app_label , model_name , field_name in sorted ( self . new_field_keys - self . old_field_keys ) : <EOL> old_model_name = self . renamed_models . get ( ( app_label , model_name ) , model_name ) <EOL> old_model_state = self . from_state . models [ app_label , old_model_name ] <EOL> field = self . new_apps . get_model ( app_label , model_name ) . _meta . get_field ( field_name ) <EOL> field_dec = self . deep_deconstruct ( field ) <EOL> for rem_app_label , rem_model_name , rem_field_name in sorted ( self . old_field_keys - self . new_field_keys ) : <EOL> if rem_app_label == app_label and rem_model_name == model_name : <EOL> old_field_dec = self . deep_deconstruct ( old_model_state . get_field_by_name ( rem_field_name ) ) <EOL> if field . remote_field and field . remote_field . model and '<STR_LIT:to>' in old_field_dec [ <NUM_LIT:2> ] : <EOL> old_rel_to = old_field_dec [ <NUM_LIT:2> ] [ '<STR_LIT:to>' ] <EOL> if old_rel_to in self . renamed_models_rel : <EOL> old_field_dec [ <NUM_LIT:2> ] [ '<STR_LIT:to>' ] = self . renamed_models_rel [ old_rel_to ] <EOL> if old_field_dec == field_dec : <EOL> if self . questioner . ask_rename ( model_name , rem_field_name , field_name , field ) : <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . RenameField ( <EOL> model_name = model_name , <EOL> old_name = rem_field_name , <EOL> new_name = field_name , <EOL> ) <EOL> ) <EOL> self . old_field_keys . remove ( ( rem_app_label , rem_model_name , rem_field_name ) ) <EOL> self . old_field_keys . add ( ( app_label , model_name , field_name ) ) <EOL> self . renamed_fields [ app_label , model_name , field_name ] = rem_field_name <EOL> break <EOL> def generate_added_fields ( self ) : <EOL> """<STR_LIT>""" <EOL> for app_label , model_name , field_name in sorted ( self . new_field_keys - self . old_field_keys ) : <EOL> self . _generate_added_field ( app_label , model_name , field_name ) <EOL> def _generate_added_field ( self , app_label , model_name , field_name ) : <EOL> field = self . new_apps . get_model ( app_label , model_name ) . _meta . get_field ( field_name ) <EOL> dependencies = [ ] <EOL> if field . remote_field and field . remote_field . model : <EOL> dependencies . extend ( self . _get_dependecies_for_foreign_key ( field ) ) <EOL> preserve_default = True <EOL> if ( not field . null and not field . has_default ( ) and not field . many_to_many and <EOL> not ( field . blank and field . empty_strings_allowed ) ) : <EOL> field = field . clone ( ) <EOL> field . default = self . questioner . ask_not_null_addition ( field_name , model_name ) <EOL> preserve_default = False <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . AddField ( <EOL> model_name = model_name , <EOL> name = field_name , <EOL> field = field , <EOL> preserve_default = preserve_default , <EOL> ) , <EOL> dependencies = dependencies , <EOL> ) <EOL> def generate_removed_fields ( self ) : <EOL> """<STR_LIT>""" <EOL> for app_label , model_name , field_name in sorted ( self . old_field_keys - self . new_field_keys ) : <EOL> self . _generate_removed_field ( app_label , model_name , field_name ) <EOL> def _generate_removed_field ( self , app_label , model_name , field_name ) : <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . RemoveField ( <EOL> model_name = model_name , <EOL> name = field_name , <EOL> ) , <EOL> dependencies = [ <EOL> ( app_label , model_name , field_name , "<STR_LIT>" ) , <EOL> ( app_label , model_name , field_name , "<STR_LIT>" ) , <EOL> ] , <EOL> ) <EOL> def generate_altered_fields ( self ) : <EOL> """<STR_LIT>""" <EOL> for app_label , model_name , field_name in sorted ( self . old_field_keys . intersection ( self . new_field_keys ) ) : <EOL> old_model_name = self . renamed_models . get ( ( app_label , model_name ) , model_name ) <EOL> old_field_name = self . renamed_fields . get ( ( app_label , model_name , field_name ) , field_name ) <EOL> old_field = self . old_apps . get_model ( app_label , old_model_name ) . _meta . get_field ( old_field_name ) <EOL> new_field = self . new_apps . get_model ( app_label , model_name ) . _meta . get_field ( field_name ) <EOL> if hasattr ( new_field , "<STR_LIT>" ) and getattr ( new_field . remote_field , "<STR_LIT>" , None ) : <EOL> rename_key = ( <EOL> new_field . remote_field . model . _meta . app_label , <EOL> new_field . remote_field . model . _meta . model_name , <EOL> ) <EOL> if rename_key in self . renamed_models : <EOL> new_field . remote_field . model = old_field . remote_field . model <EOL> old_field_dec = self . deep_deconstruct ( old_field ) <EOL> new_field_dec = self . deep_deconstruct ( new_field ) <EOL> if old_field_dec != new_field_dec : <EOL> both_m2m = old_field . many_to_many and new_field . many_to_many <EOL> neither_m2m = not old_field . many_to_many and not new_field . many_to_many <EOL> if both_m2m or neither_m2m : <EOL> preserve_default = True <EOL> if ( old_field . null and not new_field . null and not new_field . has_default ( ) and <EOL> not new_field . many_to_many ) : <EOL> field = new_field . clone ( ) <EOL> new_default = self . questioner . ask_not_null_alteration ( field_name , model_name ) <EOL> if new_default is not models . NOT_PROVIDED : <EOL> field . default = new_default <EOL> preserve_default = False <EOL> else : <EOL> field = new_field <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . AlterField ( <EOL> model_name = model_name , <EOL> name = field_name , <EOL> field = field , <EOL> preserve_default = preserve_default , <EOL> ) <EOL> ) <EOL> else : <EOL> self . _generate_removed_field ( app_label , model_name , field_name ) <EOL> self . _generate_added_field ( app_label , model_name , field_name ) <EOL> def _get_dependecies_for_foreign_key ( self , field ) : <EOL> swappable_setting = getattr ( field , '<STR_LIT>' , None ) <EOL> if swappable_setting is not None : <EOL> dep_app_label = "<STR_LIT>" <EOL> dep_object_name = swappable_setting <EOL> else : <EOL> dep_app_label = field . remote_field . model . _meta . app_label <EOL> dep_object_name = field . remote_field . model . _meta . object_name <EOL> dependencies = [ ( dep_app_label , dep_object_name , None , True ) ] <EOL> if getattr ( field . remote_field , "<STR_LIT>" , None ) and not field . remote_field . through . _meta . auto_created : <EOL> dependencies . append ( ( <EOL> field . remote_field . through . _meta . app_label , <EOL> field . remote_field . through . _meta . object_name , <EOL> None , <EOL> True , <EOL> ) ) <EOL> return dependencies <EOL> def _generate_altered_foo_together ( self , operation ) : <EOL> option_name = operation . option_name <EOL> for app_label , model_name in sorted ( self . kept_model_keys ) : <EOL> old_model_name = self . renamed_models . get ( ( app_label , model_name ) , model_name ) <EOL> old_model_state = self . from_state . models [ app_label , old_model_name ] <EOL> new_model_state = self . to_state . models [ app_label , model_name ] <EOL> old_value = old_model_state . options . get ( option_name ) or set ( ) <EOL> if old_value : <EOL> old_value = { <EOL> tuple ( <EOL> self . renamed_fields . get ( ( app_label , model_name , n ) , n ) <EOL> for n in unique <EOL> ) <EOL> for unique in old_value <EOL> } <EOL> new_value = new_model_state . options . get ( option_name ) or set ( ) <EOL> if new_value : <EOL> new_value = set ( new_value ) <EOL> if old_value != new_value : <EOL> dependencies = [ ] <EOL> for foo_togethers in new_value : <EOL> for field_name in foo_togethers : <EOL> field = self . new_apps . get_model ( app_label , model_name ) . _meta . get_field ( field_name ) <EOL> if field . remote_field and field . remote_field . model : <EOL> dependencies . extend ( self . _get_dependecies_for_foreign_key ( field ) ) <EOL> self . add_operation ( <EOL> app_label , <EOL> operation ( <EOL> name = model_name , <EOL> ** { option_name : new_value } <EOL> ) , <EOL> dependencies = dependencies , <EOL> ) <EOL> def generate_altered_unique_together ( self ) : <EOL> self . _generate_altered_foo_together ( operations . AlterUniqueTogether ) <EOL> def generate_altered_index_together ( self ) : <EOL> self . _generate_altered_foo_together ( operations . AlterIndexTogether ) <EOL> def generate_altered_db_table ( self ) : <EOL> models_to_check = self . kept_model_keys . union ( self . kept_proxy_keys ) . union ( self . kept_unmanaged_keys ) <EOL> for app_label , model_name in sorted ( models_to_check ) : <EOL> old_model_name = self . renamed_models . get ( ( app_label , model_name ) , model_name ) <EOL> old_model_state = self . from_state . models [ app_label , old_model_name ] <EOL> new_model_state = self . to_state . models [ app_label , model_name ] <EOL> old_db_table_name = old_model_state . options . get ( '<STR_LIT>' ) <EOL> new_db_table_name = new_model_state . options . get ( '<STR_LIT>' ) <EOL> if old_db_table_name != new_db_table_name : <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . AlterModelTable ( <EOL> name = model_name , <EOL> table = new_db_table_name , <EOL> ) <EOL> ) <EOL> def generate_altered_options ( self ) : <EOL> """<STR_LIT>""" <EOL> models_to_check = self . kept_model_keys . union ( <EOL> self . kept_proxy_keys <EOL> ) . union ( <EOL> self . kept_unmanaged_keys <EOL> ) . union ( <EOL> set ( self . old_unmanaged_keys ) . intersection ( self . new_model_keys ) <EOL> ) . union ( <EOL> set ( self . old_model_keys ) . intersection ( self . new_unmanaged_keys ) <EOL> ) <EOL> for app_label , model_name in sorted ( models_to_check ) : <EOL> old_model_name = self . renamed_models . get ( ( app_label , model_name ) , model_name ) <EOL> old_model_state = self . from_state . models [ app_label , old_model_name ] <EOL> new_model_state = self . to_state . models [ app_label , model_name ] <EOL> old_options = dict ( <EOL> option for option in old_model_state . options . items ( ) <EOL> if option [ <NUM_LIT:0> ] in AlterModelOptions . ALTER_OPTION_KEYS <EOL> ) <EOL> new_options = dict ( <EOL> option for option in new_model_state . options . items ( ) <EOL> if option [ <NUM_LIT:0> ] in AlterModelOptions . ALTER_OPTION_KEYS <EOL> ) <EOL> if old_options != new_options : <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . AlterModelOptions ( <EOL> name = model_name , <EOL> options = new_options , <EOL> ) <EOL> ) <EOL> def generate_altered_order_with_respect_to ( self ) : <EOL> for app_label , model_name in sorted ( self . kept_model_keys ) : <EOL> old_model_name = self . renamed_models . get ( ( app_label , model_name ) , model_name ) <EOL> old_model_state = self . from_state . models [ app_label , old_model_name ] <EOL> new_model_state = self . to_state . models [ app_label , model_name ] <EOL> if ( old_model_state . options . get ( "<STR_LIT>" ) != <EOL> new_model_state . options . get ( "<STR_LIT>" ) ) : <EOL> dependencies = [ ] <EOL> if new_model_state . options . get ( "<STR_LIT>" ) : <EOL> dependencies . append ( ( <EOL> app_label , <EOL> model_name , <EOL> new_model_state . options [ "<STR_LIT>" ] , <EOL> True , <EOL> ) ) <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . AlterOrderWithRespectTo ( <EOL> name = model_name , <EOL> order_with_respect_to = new_model_state . options . get ( '<STR_LIT>' ) , <EOL> ) , <EOL> dependencies = dependencies , <EOL> ) <EOL> def generate_altered_managers ( self ) : <EOL> for app_label , model_name in sorted ( self . kept_model_keys ) : <EOL> old_model_name = self . renamed_models . get ( ( app_label , model_name ) , model_name ) <EOL> old_model_state = self . from_state . models [ app_label , old_model_name ] <EOL> new_model_state = self . to_state . models [ app_label , model_name ] <EOL> if old_model_state . managers != new_model_state . managers : <EOL> self . add_operation ( <EOL> app_label , <EOL> operations . AlterModelManagers ( <EOL> name = model_name , <EOL> managers = new_model_state . managers , <EOL> ) <EOL> ) <EOL> def arrange_for_graph ( self , changes , graph , migration_name = None ) : <EOL> """<STR_LIT>""" <EOL> leaves = graph . leaf_nodes ( ) <EOL> name_map = { } <EOL> for app_label , migrations in list ( changes . items ( ) ) : <EOL> if not migrations : <EOL> continue <EOL> app_leaf = None <EOL> for leaf in leaves : <EOL> if leaf [ <NUM_LIT:0> ] == app_label : <EOL> app_leaf = leaf <EOL> break <EOL> if app_leaf is None and not self . questioner . ask_initial ( app_label ) : <EOL> for migration in migrations : <EOL> name_map [ ( app_label , migration . name ) ] = ( app_label , "<STR_LIT>" ) <EOL> del changes [ app_label ] <EOL> continue <EOL> if app_leaf is None : <EOL> next_number = <NUM_LIT:1> <EOL> else : <EOL> next_number = ( self . parse_number ( app_leaf [ <NUM_LIT:1> ] ) or <NUM_LIT:0> ) + <NUM_LIT:1> <EOL> for i , migration in enumerate ( migrations ) : <EOL> if i == <NUM_LIT:0> and app_leaf : <EOL> migration . dependencies . append ( app_leaf ) <EOL> if i == <NUM_LIT:0> and not app_leaf : <EOL> new_name = "<STR_LIT>" % migration_name if migration_name else "<STR_LIT>" <EOL> else : <EOL> new_name = "<STR_LIT>" % ( <EOL> next_number , <EOL> migration_name or self . suggest_name ( migration . operations ) [ : <NUM_LIT:100> ] , <EOL> ) <EOL> name_map [ ( app_label , migration . name ) ] = ( app_label , new_name ) <EOL> next_number += <NUM_LIT:1> <EOL> migration . name = new_name <EOL> for app_label , migrations in changes . items ( ) : <EOL> for migration in migrations : <EOL> migration . dependencies = [ name_map . get ( d , d ) for d in migration . dependencies ] <EOL> return changes <EOL> def _trim_to_apps ( self , changes , app_labels ) : <EOL> """<STR_LIT>""" <EOL> app_dependencies = { } <EOL> for app_label , migrations in changes . items ( ) : <EOL> for migration in migrations : <EOL> for dep_app_label , name in migration . dependencies : <EOL> app_dependencies . setdefault ( app_label , set ( ) ) . add ( dep_app_label ) <EOL> required_apps = set ( app_labels ) <EOL> old_required_apps = None <EOL> while old_required_apps != required_apps : <EOL> old_required_apps = set ( required_apps ) <EOL> for app_label in list ( required_apps ) : <EOL> required_apps . update ( app_dependencies . get ( app_label , set ( ) ) ) <EOL> for app_label in list ( changes . keys ( ) ) : <EOL> if app_label not in required_apps : <EOL> del changes [ app_label ] <EOL> return changes <EOL> @ classmethod <EOL> def suggest_name ( cls , ops ) : <EOL> """<STR_LIT>""" <EOL> if len ( ops ) == <NUM_LIT:1> : <EOL> if isinstance ( ops [ <NUM_LIT:0> ] , operations . CreateModel ) : <EOL> return ops [ <NUM_LIT:0> ] . name_lower <EOL> elif isinstance ( ops [ <NUM_LIT:0> ] , operations . DeleteModel ) : <EOL> return "<STR_LIT>" % ops [ <NUM_LIT:0> ] . name_lower <EOL> elif isinstance ( ops [ <NUM_LIT:0> ] , operations . AddField ) : <EOL> return "<STR_LIT>" % ( ops [ <NUM_LIT:0> ] . model_name_lower , ops [ <NUM_LIT:0> ] . name_lower ) <EOL> elif isinstance ( ops [ <NUM_LIT:0> ] , operations . RemoveField ) : <EOL> return "<STR_LIT>" % ( ops [ <NUM_LIT:0> ] . model_name_lower , ops [ <NUM_LIT:0> ] . name_lower ) <EOL> elif len ( ops ) > <NUM_LIT:1> : <EOL> if all ( isinstance ( o , operations . CreateModel ) for o in ops ) : <EOL> return "<STR_LIT:_>" . join ( sorted ( o . name_lower for o in ops ) ) <EOL> return "<STR_LIT>" % datetime . datetime . now ( ) . strftime ( "<STR_LIT>" ) <EOL> @ classmethod <EOL> def parse_number ( cls , name ) : <EOL> """<STR_LIT>""" <EOL> match = re . match ( r'<STR_LIT>' , name ) <EOL> if match : <EOL> return int ( match . group ( ) ) <EOL> return None </s>
