
 X                 @   s   d  d l  m Z d  d l Z d  d l Z d  d l m Z d  d l m Z d  d l m	 Z	 d  d l
 m Z d  d l m Z d  d l m Z d  d	 l m Z d  d
 l m Z d  d l m Z m Z m Z d  d l m Z d d l m Z Gd d   d e  Z d S)    )unicode_literalsN)chain)settings)models)
operations)	Migration)AlterModelOptions)MigrationOptimizer)MigrationQuestioner)COMPILED_REGEX_TYPERegexObjectget_migration_name_timestamp)six   )stable_topological_sortc               @   s  e  Z d  Z d Z d d d  Z d d d d d  Z d d   Z d	 d
   Z d d d d  Z d d   Z	 d d   Z
 d d d  Z d d   Z d d   Z d d   Z d d d d  Z d d   Z d d   Z d  d!   Z d" d#   Z d$ d%   Z d& d'   Z d( d)   Z d* d+   Z d, d-   Z d. d/   Z d0 d1   Z d2 d3   Z d4 d5   Z d6 d7   Z d8 d9   Z d: d;   Z d< d=   Z  d> d?   Z! d@ dA   Z" dB dC   Z# d dD dE  Z$ dF dG   Z% e& dH dI    Z' e& dJ dK    Z( d S)LMigrationAutodetectora  
    Takes a pair of ProjectStates, and compares them to see what the
    first would need doing to make it match the second (the second
    usually being the project's current state).

    Note that this naturally operates on entire projects at a time,
    as it's likely that changes interact (for example, you can't
    add a ForeignKey without having a migration to add the table it
    depends on first). A user interface may offer single-app usage
    if it wishes, with the caveat that it may not always be possible.
    Nc             C   sA   | |  _  | |  _ | p t   |  _ d d   | j D |  _ d  S)Nc             S   s   h  |  ] \ } } |  q S r   ).0Zappmodelr   r   O/home/ubuntu/projects/ifolica/build/django/django/db/migrations/autodetector.py	<setcomp>'   s   	 z1MigrationAutodetector.__init__.<locals>.<setcomp>)
from_stateto_stater
   
questionerr   existing_apps)selfr   r   r   r   r   r   __init__#   s    		zMigrationAutodetector.__init__c             C   sF   |  j  | |  } |  j | | |  } | rB |  j | |  } n  | S)z
        Main entry point to produce a list of applicable changes.
        Takes a graph to base names on and an optional set of apps
        to try and restrict to (restriction is not guaranteed)
        )_detect_changesarrange_for_graph_trim_to_apps)r   graphZtrim_to_appsconvert_appsmigration_namechangesr   r   r   r#   )   s
    zMigrationAutodetector.changesc                st  t  | t  r&   f d d   | D St  | t  rR t   f d d   | D  St  | t  r~   f d d   | j   D St  | t j  r | j   j | j	    j | j
  f St  | t  r t |  St  | t  r | St | d  rl| j   } t  | t j  r$| d d	  } n  | \ } } } |   f d
 d   | D   f d d   | j   D f S| Sd	 S)z
        Recursive deconstruction for a field and its arguments.
        Used for full comparison for rename/alter; sometimes a single-level
        deconstruction will not compare correctly.
        c                s   g  |  ] }   j  |   q Sr   )deep_deconstruct)r   value)r   r   r   
<listcomp><   s   	 z:MigrationAutodetector.deep_deconstruct.<locals>.<listcomp>c             3   s   |  ] }   j  |  Vq d  S)N)r$   )r   r%   )r   r   r   	<genexpr>>   s    z9MigrationAutodetector.deep_deconstruct.<locals>.<genexpr>c                s(   i  |  ] \ } }   j  |  |  q Sr   )r$   )r   keyr%   )r   r   r   
<dictcomp>A   s   	z:MigrationAutodetector.deep_deconstruct.<locals>.<dictcomp>deconstructr   Nc                s   g  |  ] }   j  |   q Sr   )r$   )r   r%   )r   r   r   r&   T   s   	 c                s(   i  |  ] \ } }   j  |  |  q Sr   )r$   )r   r(   r%   )r   r   r   r)   V   s   	)
isinstancelisttupledictitems	functoolspartialfuncr$   argskeywordsr   r   typehasattrr*   r   ZField)r   objZdeconstructedpathr3   kwargsr   )r   r   r$   5   s.    (
z&MigrationAutodetector.deep_deconstructc             C   sf   g  } xY t  |  D]K \ } } |  j |  } | j rQ | j j rQ | d d =n  | j |  q W| S)z
        Return a definition of the fields that ignores field names and
        what related fields actually relate to.
        Used for detecting renames (as, of course, the related fields
        change during renames)
           to)sortedr$   remote_fieldr   append)r   fieldsZ
fields_defnamefieldZdeconstructionr   r   r   only_relation_agnostic_fields]   s    z3MigrationAutodetector.only_relation_agnostic_fieldsc             C   s  i  |  _  |  j j |  _ |  j j |  _ g  |  _ g  |  _ g  |  _	 g  |  _
 g  |  _ g  |  _ x t |  j j j    D] \ } } |  j j | |  } | j j s |  j	 j | | f  qv | |  j j k rv | j j r |  j j | | f  q|  j j | | f  qv qv Wx t |  j j j    D] \ } } |  j j | |  } | j j so|  j j | | f  q)| |  j j k s| r)| | k r)| j j r|  j j | | f  q|  j
 j | | f  q)q)W|  j   |  j   |  j   |  j   |  j   |  j   |  j   |  j   |  j   |  j   |  j    |  j!   |  j"   |  j#   |  j$   |  j%   |  j&   |  j'   |  j( |  |  j)   |  j* S)aY  
        Returns a dict of migration plans which will achieve the
        change from from_state to to_state. The dict has app labels
        as keys and a list of migrations as values.

        The resulting migrations aren't specially named, but the names
        do matter for dependencies inside the set.

        convert_apps is the list of apps to convert to use migrations
        (i.e. to make initial migrations for, in the usual case)

        graph is an optional argument that, if provided, can help improve
        dependency generation and avoid potential circular dependencies.
        )+generated_operationsr   Zconcrete_appsold_appsr   Zappsnew_appsold_model_keysold_proxy_keysold_unmanaged_keysnew_model_keysnew_proxy_keysnew_unmanaged_keysr<   r   keys	get_model_metamanagedr>   Z	real_appsproxygenerate_renamed_models_prepare_field_lists_generate_through_model_mapgenerate_deleted_modelsgenerate_created_modelsgenerate_deleted_proxiesgenerate_created_proxiesgenerate_altered_optionsgenerate_altered_managersgenerate_renamed_fieldsgenerate_removed_fieldsgenerate_added_fieldsgenerate_altered_fields generate_altered_unique_togethergenerate_altered_index_togethergenerate_altered_db_table&generate_altered_order_with_respect_to_sort_migrations_build_migration_list_optimize_migrations
migrations)r   r!   r    almnr   r   r   r   r   l   s^    							%%


















z%MigrationAutodetector._detect_changesc                s8  t  |  j  j |  j  |  _ t  |  j  j |  j  |  _ t  |  j  j |  j	  |  _
 i  |  _ t    |  _ t    |  _ x t |  j  D] \    |  j j    f   } |  j j   | f } |  j j    f } |  j j    f d d   | j D  |  j j    f d d   | j D  q Wd S)z
        Prepare field lists, and prepare a list of the fields that used
        through models in the old state so we can make dependencies
        from the through model deletion to the field that uses it.
        c             3   s$   |  ] \ } }    | f Vq d  S)Nr   )r   xy)	app_label
model_namer   r   r'      s    z=MigrationAutodetector._prepare_field_lists.<locals>.<genexpr>c             3   s$   |  ] \ } }    | f Vq d  S)Nr   )r   rh   ri   )rj   rk   r   r   r'      s    N)setrF   intersectionrI   kept_model_keysrG   rJ   kept_proxy_keysrH   rK   kept_unmanaged_keysthrough_usersold_field_keysnew_field_keysr<   renamed_modelsgetr   r   r   updater?   )r   old_model_nameold_model_statenew_model_stater   )rj   rk   r   rR      s    	)z*MigrationAutodetector._prepare_field_listsc       	      C   s  x t  |  j  D] \ } } |  j j | | f |  } |  j j | | f } x | j D] \ } } |  j j | |  j	 j
 |  } t | d  rW t | j d d  rW | j j j	 j rW | j j j	 j | j j j	 j f } | | | f |  j | <qW qW Wq Wd S)z.
        Through model map generation
        r=   throughN)r<   rF   rt   ru   r   r   r?   rD   rM   rN   	get_fieldr6   getattrr=   rz   auto_createdrj   rk   rq   )	r   rj   rk   rw   rx   
field_namerA   	old_fieldZthrough_keyr   r   r   rS      s    !$z1MigrationAutodetector._generate_through_model_mapc             C   s  i  |  _  t d d   |  j j   D  } d } x| rx%t |  j j    D]} g  } t   } xt |  j |  D]} d } t   }	 x| j D]}
 d } |
 d d k rt	 t
 |
 d  j d  \ } } |
 } | | j   |
 d	 |
 d
 f }
 d } n  |
 d | k r |
 d d k r x= |  j j |
 d g   D]" } |  j | |
  r?d } Pq?q?W| soPq5| r|	 j | d | d f  q5|
 d |  j  k r|	 j |
 d |  j  |
 d d j f  q5| r,| r| j |
 d  r|	 j | j |
 d  d  q2|	 j |
 d d f  q5d } q q W| rz| j |  | j |	  |  j | d d  |  j | <qy Pqy W| s| rP |  j | s| rCt t d  t f i g  d 6g  d 6 } | d t |  j  j | g    d |  } t |  | _ | | _ | |  j k | _ |  j  j | g   j |  d } q^| |  j | |  j | <qP qP Wt d d   |  j j   D  } | | k r| sd } qt d |  j   n  | } q4 Wd S)au  
        We need to chop the lists of operations up into migrations with
        dependencies on each other. We do this by stepping up an app's list of
        operations until we find one that has an outgoing dependency that isn't
        in another app's migration yet (hasn't been chopped off its list). We
        then chop off the operations before it into a migration and move onto
        the next app. If we loop back around without doing anything, there's a
        circular dependency (which _should_ be impossible as the operations are
        all split at this point so they can't depend and be depended on).
        c             s   s   |  ] } t  |  Vq d  S)N)len)r   rh   r   r   r   r'      s    z>MigrationAutodetector._build_migration_list.<locals>.<genexpr>FTr   __setting__r   .r:      	__first__Nr   r   dependencieszauto_%ic             s   s   |  ] } t  |  Vq d  S)N)r   )r   rh   r   r   r   r'   9  s    z)Cannot resolve operation dependencies: %r)re   sumrC   valuesr<   rL   rl   r,   
_auto_depsr|   r   splitlowerru   check_dependencyaddr@   
leaf_nodesr>   rv   r5   strr   r   r   r   r   initial
setdefault
ValueError)r   r    Znum_opsZ	chop_moderj   Zchoppedr   	operationZdeps_satisfiedZoperation_dependenciesdepZis_swappable_depZresolved_app_labelZresolved_object_nameZoriginal_depZother_operationsubclassinstanceZnew_num_opsr   r   r   rc      sl    	"			" 	  ,!!),		"	z+MigrationAutodetector._build_migration_listc             C   s   x t  |  j j    D] \ } } d d   | D } xl | D]d } x[ | j D]P } | d | k rL x7 | D], } |  j | |  ri | | j |  qi qi WqL qL Wq< Wt | |  |  j | <q Wd S)z
        Reorder to make things possible. The order we have already isn't bad,
        but we need to pull a few things around so FKs work nicely inside the
        same app
        c             S   s   i  |  ] } t    |  q Sr   )rl   )r   opr   r   r   r)   I  s   	 z:MigrationAutodetector._sort_migrations.<locals>.<dictcomp>r   N)r<   rC   r/   r   r   r   r   )r   rj   opsZdependency_graphr   r   Zop2r   r   r   rb   A  s    "#z&MigrationAutodetector._sort_migrationsc             C   s   x` |  j  j   D]O \ } } x@ t | | d d    D]% \ } } | j j | | j f  q6 Wq WxF |  j  j   D]5 \ } } x& | D] } t t | j   | _ q Wqs WxL |  j  j   D]; \ } } x, | D]$ } t   j	 | j
 d | | _
 q Wq Wd  S)Nr   rj   )re   r/   zipr   r>   r@   r,   rl   r	   optimizer   )r   rj   re   m1m2	migrationr   r   r   rd   T  s    &! z*MigrationAutodetector._optimize_migrationsc                s    d d k rI   d d k rI t  | t j  oH | j   d j   k S  d d k	 r   d d k r t  | t j  r | j   d j   k r t   f d d   | j D  p t  | t j  o | j   d j   k o | j   d j   k S  d d k	 rZ  d d k rZt  | t j	  oY| j   d j   k oY| j   d j   k S  d d k r  d d k rt  | t j
  o| j   d j   k S  d d k	 r  d d	 k rt  | t j  o| j   d j   k o| j   d j   k S  d d k	 rs  d d
 k rst  | t j  or| j   d j   k or| j p\d j     d j   k S  d d k	 r  d d k rt  | t j t j f  o| j   d j   k St d   f   d S)zw
        Returns ``True`` if the given operation depends on the given dependency,
        ``False`` otherwise.
        r:   Nr   Tr   c             3   s%   |  ] \ } }   d  | k Vq d S)r:   Nr   )r   rh   ri   )
dependencyr   r   r'   u  s    z9MigrationAutodetector.check_dependency.<locals>.<genexpr>Falterorder_wrt_unset foo_together_changezCan't handle dependency %r)r+   r   CreateModel
name_lowerr   anyr?   AddFieldmodel_name_lowerRemoveFieldDeleteModel
AlterFieldAlterOrderWithRespectToorder_with_respect_toAlterUniqueTogetherAlterIndexTogetherr   )r   r   r   r   )r   r   r   d  s<      "    # z&MigrationAutodetector.check_dependencyFc             C   sW   | p	 g  | _  | r7 |  j j | g   j d |  n |  j j | g   j |  d  S)Nr   )r   rC   r   insertr>   )r   rj   r   r   	beginningr   r   r   add_operation  s    "z#MigrationAutodetector.add_operationc             C   s   y |  j  j | d | d  } d d   | j D } d | d | d f } | j j s d | k s d | k s t j j   | j   k r d | d d | d f SWn t k
 r Yn X| S)	z
        Sorting key function that places potential swappable models first in
        lists of created models (only real way to solve #22783)
        r   r   c             S   s   g  |  ] } | j   q Sr   )__name__)r   baser   r   r   r&     s   	 z=MigrationAutodetector.swappable_first_key.<locals>.<listcomp>z%s.%sZAbstractUserZAbstractBaseUserZ___)	rE   rM   	__bases__rN   Z	swappabler   ZAUTH_USER_MODELr   LookupError)r   itemr   Z
base_namesZstring_versionr   r   r   swappable_first_key  s    z)MigrationAutodetector.swappable_first_keyc          	   C   s  i  |  _  i  |  _ t |  j  t |  j  } xnt |  D]`\ } } |  j j | | f } |  j | j	  } t |  j  t |  j  } x| D]\ } } | | k r |  j
 j | | f }	 |  j |	 j	  }
 | |
 k r|  j j |	 |  r|  j | t j d |	 j d | j   | |  j  | | f <d |	 j |	 j f } d | j | j f |  j | <|  j j | | f  |  j j | | f  Pqqq q Wq; Wd S)z
        Finds any renamed models, and generates the operations for them,
        and removes the old entry from the model lists.
        Must be run before other model-level generation.
        old_namenew_namez%s.%sN)rt   renamed_models_relrl   rI   rF   r<   r   r   rB   r?   r   r   Zask_rename_modelr   r   ZRenameModelr@   rj   remover>   )r   added_modelsrj   rk   model_stateZmodel_fields_defZremoved_modelsrem_app_labelrem_model_nameZrem_model_stateZrem_model_fields_defZrenamed_models_rel_keyr   r   r   rQ     s4    				z-MigrationAutodetector.generate_renamed_modelsc                s  t  |  j  j |  j  } t  |  j  | } t  |  j  | } t t | d |  j d d t | d |  j d d  } x!| D]\    |  j	 j
    f } |  j j     j } i   d } x | j D] } | j r | j j r#| j r| j j } q#| j j s#|  | j <q#n  t | j d d  r^| j j j j r^|  | j <q^q q Wxe | j D]Z } | j j r|  | j <n  t | j d d  rl| j j j j rl|  | j <qlqlW| j j d d  }	 | j j d d  }
 | j j d d  }    d d	 f g } xc | j D]X } t | t j  r(d
 | k r(| j d
 d  \ } } | j | | d d f  q(q(W| r| j | j j  | j j! d d f  n  |  j"   t# j$ d | j d  f d d   | j% D d | j d | j d | j&  d | d d | j' s#q n  x t  j(    D]n \ } } |  j) |  } | j    d d f  |  j"   t# j* d  d | d |  d t+ t  |   q6W   f d d   t  j(    D } | j    d d f  |	 r|  j"   t# j, d  d |	  d | n  |
 rK|  j"   t# j- d  d |
  d | n  | r |  j"   t# j. d  d |  d    | d f    d d f g q q Wd S)a  
        Find all new models (both managed and unmanaged) and make create
        operations for them as well as separate operations to create any
        foreign key or M2M relationships (we'll optimize these back in later
        if we can).

        We also defer any model options that refer to collections of fields
        that might be deferred (e.g. unique_together, index_together).
        r(   reverseTNrz   unique_togetherindex_togetherr   Fr   r   r@   r?   c                s&   g  |  ] } | d    k r |  q S)r   r   )r   d)related_fieldsr   r   r&   &  s   	 zAMigrationAutodetector.generate_created_models.<locals>.<listcomp>optionsbasesmanagersr   r   rk   rA   c                s(   g  |  ] \ } }    | d  f  q S)Tr   )r   r@   rA   )rj   rk   r   r   r&   D  s   	)/rl   rF   unionrH   rI   rK   r   r<   r   r   r   rE   rM   rN   local_fieldsr=   r   Zprimary_keyZparent_linkr@   r|   rz   r}   local_many_to_manyr   popr   r+   r   string_typesr   r>   rj   object_namer   r   r   r?   r   rO   r/    _get_dependecies_for_foreign_keyr   r,   r   r   r   )r   Zold_keysr   Zadded_unmanaged_modelsZall_added_modelsr   Z
model_optsZprimary_key_relrA   r   r   r   r   r   base_app_label	base_namer@   Zrelated_dependenciesr   )rj   rk   r   r   rU     s    
		( 											
		
		z-MigrationAutodetector.generate_created_modelsc       	      C   s,  t  |  j  t  |  j  } x	t |  D] \ } } |  j j | | f } | j j d  sc t  | | d d f g } xc | j	 D]X } t
 | t j  r d | k r | j d d  \ } } | j | | d d f  q q W|  j | t j d | j d g  d	 | j d
 | j	 d | j  d | q) Wd S)a	  
        Makes CreateModel statements for proxy models.
        We use the same statements as that way there's less code duplication,
        but of course for proxy models we can skip all that pointless field
        stuff and just chuck out an operation.
        rP   NFr   r   Tr@   r?   r   r   r   r   )rl   rJ   rG   r<   r   r   r   ru   AssertionErrorr   r+   r   r   r   r>   r   r   r   r@   r   )	r   addedrj   rk   r   r   r   r   r   r   r   r   rW   g  s$     				z.MigrationAutodetector.generate_created_proxiesc          	   C   s  t  |  j  j |  j  } t  |  j  | } t  |  j  | } t t |  t |   } x9| D]1\ } } |  j j	 | | f } |  j
 j | |  } | j j s qc n  i  }	 xt | j j D]f }
 |
 j r |
 j j r |
 |	 |
 j <n  t |
 j d d  r%|
 j j j j r%|
 |	 |
 j <q%q q Wxh | j j D]Z }
 |
 j j rX|
 |	 |
 j <n  t |
 j d d  r6|
 j j j j r6|
 |	 |
 j <q6q6W| j j d d  } | j j d d  } | r|  j | t j d | d d   n  | r|  j | t j d | d d   n  xB t |	 j    D]. \ } }
 |  j | t j d | d |   q'Wg  } x| | j j D]n } | j j j  } | j j j! } | j" j } | j# | | | d f  | j$ sl| j# | | | d f  qlqlWx9 t |	 j    D]% \ } }
 | j# | | | d f  qW|  j% j& | | j' f  } | rc| j# | d	 | d
 | d d f  n  |  j | t j( d | j  d t) t  |   qc Wd S)a  
        Find all deleted models (managed and unmanaged) and make delete
        operations for them as well as separate operations to delete any
        foreign key or M2M relationships (we'll optimize these back in later
        if we can).

        We also bring forward removal of any model options that refer to
        collections of fields - the inverse of generate_created_models().
        rz   Nr   r   r@   rk   Fr   r   r   r:   r   )*rl   rI   r   rK   rF   rH   r   r<   r   r   rD   rM   rN   rO   r   r=   r   r@   r|   rz   r}   r   r   r   r   r   r   r   r/   r   Zrelated_objectsZrelated_modelrj   r   rA   r>   many_to_manyrq   ru   r   r   r,   )r   Znew_keysZdeleted_modelsZdeleted_unmanaged_modelsZall_deleted_modelsrj   rk   r   r   r   rA   r   r   r@   r   Zrelated_objectZrelated_object_app_labelr   r~   Zthrough_userr   r   r   rT     sx    
	(				 (	z-MigrationAutodetector.generate_deleted_modelsc             C   s   t  |  j  t  |  j  } xg t |  D]Y \ } } |  j j | | f } | j j d  sc t  |  j	 | t
 j d | j   q) Wd S)z@
        Makes DeleteModel statements for proxy models.
        rP   r@   N)rl   rG   rJ   r<   r   r   r   ru   r   r   r   r   r@   )r   Zdeletedrj   rk   r   r   r   r   rV     s    	z.MigrationAutodetector.generate_deleted_proxiesc             C   s  i  |  _  xt |  j |  j  D]\ } } } |  j j | | f |  } |  j j | | f } |  j j	 | |  j
 j |  } |  j |  } xUt |  j |  j  D]=\ } }	 }
 | | k r |	 | k r |  j | j |
   } | j rC| j j rCd | d k rC| d d } | |  j k rC|  j | | d d <qCn  | | k r|  j j | |
 | |  r|  j | t j d | d |
 d |   |  j j | |	 |
 f  |  j j | | | f  |
 |  j  | | | f <Pqqq q Wq  Wd S)z*
        Works out renamed fields
        r;   r:   rk   r   r   N)renamed_fieldsr<   rs   rr   rt   ru   r   r   rE   rM   rN   r{   r$   Zget_field_by_namer=   r   r   r   Z
ask_renamer   r   ZRenameFieldr   r   )r   rj   rk   r~   rw   rx   rA   Z	field_decr   r   Zrem_field_nameold_field_decZ
old_rel_tor   r   r   rZ     s2    	&!&%	
z-MigrationAutodetector.generate_renamed_fieldsc             C   sA   x: t  |  j |  j  D]" \ } } } |  j | | |  q Wd S)z-
        Fields that have been added
        N)r<   rs   rr   _generate_added_field)r   rj   rk   r~   r   r   r   r\     s    &z+MigrationAutodetector.generate_added_fieldsc             C   sX  |  j  j | |  j j |  } g  } | j rU | j j rU | j |  j |   n  d } t j	 t j
 t j f } | j r | j   r | j r | j o | j r t | |  o | j r | j   } t | |  r | j r |  j j | |  | _ n |  j j | |  | _ d } n  |  j | t j d | d | d | d |  d | d  S)NTFrk   r@   rA   preserve_defaultr   )rE   rM   rN   r{   r=   r   extendr   r   Z	DateFieldZDateTimeFieldZ	TimeFieldnullhas_defaultr   ZblankZempty_strings_allowedr+   Zauto_nowcloneZauto_now_addr   Zask_auto_now_add_additiondefaultZask_not_null_additionr   r   r   )r   rj   rk   r~   rA   r   r   Ztime_fieldsr   r   r   r     s.    !
			z+MigrationAutodetector._generate_added_fieldc             C   sA   x: t  |  j |  j  D]" \ } } } |  j | | |  q Wd S)z0
        Fields that have been removed.
        N)r<   rr   rs   _generate_removed_field)r   rj   rk   r~   r   r   r   r[   <  s    &z-MigrationAutodetector.generate_removed_fieldsc          	   C   sJ   |  j  | t j d | d |  d | | | d f | | | d f g d  S)Nrk   r@   r   r   r   )r   r   r   )r   rj   rk   r~   r   r   r   r   C  s    		z-MigrationAutodetector._generate_removed_fieldc             C   s  xt  |  j j |  j   D]\ } } } |  j j | | f |  } |  j j | | | f |  } |  j j | |  j	 j
 |  } |  j j | |  j	 j
 |  } t | d  rt | j d d  r| j j j	 j | j j j	 j f } | |  j k r| j j | j _ qn  t | d  rt | j d d  r| j j j	 j | j j j	 j f } | |  j k r| j j | j _ qn  |  j |  }	 |  j |  }
 |	 |
 k r | j o| j } | j o| j } | s| rd } | j rU| j rU| j   rU| j rU| j   } |  j j | |  } | t j k	 r[| | _ d } q[n | } |  j | t j d | d | d	 | d
 |   q|  j  | | |  |  j! | | |  q q Wd S)z0
        Fields that have been altered.
        r=   r   Nrz   TFrk   r@   rA   r   )"r<   rr   rm   rs   rt   ru   r   rD   rM   rN   r{   rE   r6   r|   r=   r   rj   rk   rz   r$   r   r   r   r   r   Zask_not_null_alterationr   ZNOT_PROVIDEDr   r   r   r   r   r   )r   rj   rk   r~   rw   Zold_field_namer   Z	new_fieldZ
rename_keyr   Znew_field_decZboth_m2mZneither_m2mr   rA   Znew_defaultr   r   r   r]   S  sN    +!!$$ 
		z-MigrationAutodetector.generate_altered_fieldsc             C   s   t  | d d   } | d  k	 r- d } | } n$ | j j j j } | j j j j } | | d  d f g } t  | j d d   r | j j j j r | j | j j j j | j j j j d  d f  n  | S)Nswappable_settingr   Trz   )	r|   r=   r   rN   rj   r   rz   r}   r>   )r   rA   r   dep_app_labelZdep_object_namer   r   r   r   r     s    	(z6MigrationAutodetector._get_dependecies_for_foreign_keyc          	      s  | j  } xt  j  D]u\     j j    f   }  j j   | f }  j j    f } | j j |  p t	   } | r     f d d   | D } n  | j j |  p t	   } | r t	 |  } n  | | k r g  } xn | D]f }	 x] |	 D]U }
  j
 j     j j |
  } | j r| j j r| j  j |   qqWq W j   | d  i | | 6 d | q q Wd  S)Nc                s5   h  |  ]+ } t      f d  d   | D   q S)c             3   s-   |  ]# }  j  j    | f |  Vq d  S)N)r   ru   )r   n)rj   rk   r   r   r   r'     s   zQMigrationAutodetector._generate_altered_foo_together.<locals>.<setcomp>.<genexpr>)r-   )r   unique)rj   rk   r   r   r   r     s   	zGMigrationAutodetector._generate_altered_foo_together.<locals>.<setcomp>r@   r   )option_namer<   rn   rt   ru   r   r   r   r   rl   rE   rM   rN   r{   r=   r   r   r   r   )r   r   r   rw   rx   ry   	old_valueZ	new_valuer   Zfoo_togethersr~   rA   r   )rj   rk   r   r   _generate_altered_foo_together  s2    	!!z4MigrationAutodetector._generate_altered_foo_togetherc             C   s   |  j  t j  d  S)N)r   r   r   )r   r   r   r   r^     s    z6MigrationAutodetector.generate_altered_unique_togetherc             C   s   |  j  t j  d  S)N)r   r   r   )r   r   r   r   r_     s    z5MigrationAutodetector.generate_altered_index_togetherc       	      C   s   |  j  j |  j  j |  j  } x t |  D] \ } } |  j j | | f |  } |  j j | | f } |  j	 j | | f } | j
 j d  } | j
 j d  } | | k r. |  j | t j d | d |   q. q. Wd  S)NZdb_tabler@   table)rn   r   ro   rp   r<   rt   ru   r   r   r   r   r   r   ZAlterModelTable)	r   models_to_checkrj   rk   rw   rx   ry   Zold_db_table_nameZnew_db_table_namer   r   r   r`     s    !	z/MigrationAutodetector.generate_altered_db_tablec       	      C   s:  |  j  j |  j  j |  j  j t |  j  j |  j   j t |  j  j |  j	   } x t
 |  D] \ } } |  j j | | f |  } |  j j | | f } |  j j | | f } t d d   | j j   D  } t d d   | j j   D  } | | k rj |  j | t j d | d |   qj qj Wd S)z
        Works out if any non-schema-affecting options have changed and
        makes an operation to represent them in state changes (in case Python
        code in migrations needs them)
        c             s   s(   |  ] } | d  t  j k r | Vq d S)r   N)r   ALTER_OPTION_KEYS)r   optionr   r   r   r'     s    zAMigrationAutodetector.generate_altered_options.<locals>.<genexpr>c             s   s(   |  ] } | d  t  j k r | Vq d S)r   N)r   r   )r   r   r   r   r   r'     s    r@   r   N)rn   r   ro   rp   rl   rH   rm   rI   rF   rK   r<   rt   ru   r   r   r   r.   r   r/   r   r   r   )	r   r   rj   rk   rw   rx   ry   Zold_optionsnew_optionsr   r   r   rX     s&    		z.MigrationAutodetector.generate_altered_optionsc          	   C   s  x t  |  j  D] \ } } |  j j | | f |  } |  j j | | f } |  j j | | f } | j j d  | j j d  k r g  } | j j d  r | j | | | j d d f  n  |  j	 | t
 j d | d | j j d   d | q q Wd  S)Nr   Tr@   r   )r<   rn   rt   ru   r   r   r   r   r>   r   r   r   )r   rj   rk   rw   rx   ry   r   r   r   r   ra     s&    
	z<MigrationAutodetector.generate_altered_order_with_respect_toc             C   s   x t  |  j  D] \ } } |  j j | | f |  } |  j j | | f } |  j j | | f } | j | j k r |  j | t	 j
 d | d | j   q q Wd  S)Nr@   r   )r<   rn   rt   ru   r   r   r   r   r   r   ZAlterModelManagers)r   rj   rk   rw   rx   ry   r   r   r   rY     s    	z/MigrationAutodetector.generate_altered_managersc                s  | j    } i    xt | j    D]\ } } | s= q% n  d } x( | D]  } | d | k rJ | } PqJ qJ W| d k r |  j j |  r x' | D] }	 | d f   | |	 j f <q W| | =q% n  | d k r d }
 n |  j | d  p d d }
 x t |  D] \ } }	 | d k r4| r4|	 j j	 |  n  | d k r`| r`| rWd | n d } n, d |
 | p|  j
 |	 j  d d  f } | | f   | |	 j f <|
 d 7}
 | |	 _ qWq% WxJ | j   D]< \ } } x- | D]% }	   f d	 d
   |	 j D |	 _ qWqW| S)z
        Takes in a result from changes() and a MigrationGraph,
        and fixes the names and dependencies of the changes so they
        extend the graph from the leaf nodes for each app.
        Nr   r   r   z0001_%sZ0001_initialz%04i_%sd   c                s"   g  |  ] }   j  | |   q Sr   )ru   )r   r   )name_mapr   r   r&   [  s   	 z;MigrationAutodetector.arrange_for_graph.<locals>.<listcomp>)r   r,   r/   r   Zask_initialr@   parse_number	enumerater   r>   suggest_namer   )r   r#   r    r"   Zleavesrj   re   Zapp_leafZleafr   Znext_numberir   r   )r   r   r   -  sB    	&
'z'MigrationAutodetector.arrange_for_graphc             C   s  i  } xa | j    D]S \ } } xD | D]< } x3 | j D]( \ } } | j | t    j |  q6 Wq& Wq Wt |  }	 d }
 xO |
 |	 k r t |	  }
 x0 t |	  D]" } |	 j | j | t     q Wq Wx0 t | j    D] } | |	 k r | | =q q W| S)a9  
        Takes changes from arrange_for_graph and set of app labels and
        returns a modified set of changes which trims out as many migrations
        that are not in app_labels as possible.
        Note that some other migrations may still be present, as they may be
        required dependencies.
        N)	r/   r   r   rl   r   r,   rv   ru   rL   )r   r#   Z
app_labelsZapp_dependenciesrj   re   r   r   r@   Zrequired_appsZold_required_appsr   r   r   r   ^  s    	($z#MigrationAutodetector._trim_to_appsc             C   s  t  |  d k r t | d t j  r3 | d j St | d t j  rX d | d j St | d t j  r d | d j | d j f St | d t j  rd | d j | d j f SnN t  |  d k rt	 d d   | D  rd j
 t d	 d   | D   Sn  d
 t   S)z
        Given a set of operations, suggests a name for the migration
        they might represent. Names are not guaranteed to be unique,
        but we put some effort in to the fallback name to avoid VCS conflicts
        if we can.
        r   r   z	delete_%sz%s_%szremove_%s_%sc             s   s!   |  ] } t  | t j  Vq d  S)N)r+   r   r   )r   or   r   r   r'     s    z5MigrationAutodetector.suggest_name.<locals>.<genexpr>_c             s   s   |  ] } | j  Vq d  S)N)r   )r   r   r   r   r   r'     s    zauto_%s)r   r+   r   r   r   r   r   r   r   alljoinr<   r   )clsr   r   r   r   r   y  s    #z"MigrationAutodetector.suggest_namec             C   s,   t  j d |  } | r( t | j    Sd S)z
        Given a migration name, tries to extract a number from the
        beginning of it. If no number found, returns None.
        z^\d+N)rematchintgroup)r   r@   r   r   r   r   r     s    z"MigrationAutodetector.parse_number))r   
__module____qualname____doc__r   r#   r$   rB   r   rR   rS   rc   rb   rd   r   r   r   rQ   rU   rW   rT   rV   rZ   r\   r   r[   r   r]   r   r   r^   r_   r`   rX   ra   rY   r   r   classmethodr   r   r   r   r   r   r      sJ   (V[?%"]!9''1r   )
__future__r   r0   r   	itertoolsr   Zdjango.confr   Z	django.dbr   Zdjango.db.migrationsr   Zdjango.db.migrations.migrationr   Z&django.db.migrations.operations.modelsr   Zdjango.db.migrations.optimizerr	   Zdjango.db.migrations.questionerr
   Zdjango.db.migrations.utilsr   r   r   Zdjango.utilsr   Ztopological_sortr   objectr   r   r   r   r   <module>   s   