ó
¸9—^c           @   sŽ   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 „  Z
 d „  Z d „  Z d	 „  Z d
 e f d „  ƒ  YZ d S(   iÿÿÿÿ(   t   apps(   t   GenericForeignKey(   t   BaseCommand(   t   transaction(   t   signalcommandc          C   sc   t  j ƒ  }  d } x* |  D]" } d | | j f GH| d 7} q Wt t d ƒ ƒ } |  | d } | S(   Ni   s   %s. %ss=   Enter the number of the model you would like to de-duplicate:(   R    t
   get_modelst   __name__t   intt   input(   t   modelst   iteratort   modelt   model_choicet   model_to_deduplicate(    (    s]   /tmp/pip-unpacked-wheel-a0M10Y/django_extensions/management/commands/merge_model_instances.pyt   get_model_to_deduplicate
   s    c         C   sÄ  g  |  j  j ƒ  D] } | j ^ q } d } x' | D] } d | | f GH| d 7} q2 Wt } x? | sœ t t d ƒ ƒ } | t d | ƒ k r” t } q^ d GHq^ W| | d g } t } x	| s¿g  | D] } | | k rÄ | ^ qÄ }	 d } x' |	 D] } d | | f GH| d 7} qï Wd GHt } xœ | s»d GHd j | ƒ d GHt d ƒ }
 |
 d	 k rdt } t } q t |
 ƒ t	 t d t
 |	 ƒ d ƒ ƒ k r³| |	 t |
 ƒ d g 7} t } q d GHq Wq· W| S(
   Ni   s   %s. %ssE   Enter the number of the (first) field you would like to de-duplicate.s    Invalid input. Please try again.s   C. Done adding fields.s8   You are currently deduplicating on the following fields:s   
s    
                Enter the number of the field you would like to de-duplicate.
                If you have entered all fields, enter C to continue.
            t   C(   t   _metat
   get_fieldst   namet   FalseR   R   t   ranget   Truet   joint   listt   len(   R   t   fieldt   fieldsR
   t	   validatedt   first_fieldt   fields_to_deduplicatet   donet   ft   available_fieldst   additional_field(    (    s]   /tmp/pip-unpacked-wheel-a0M10Y/django_extensions/management/commands/merge_model_instances.pyt   get_field_names   sD    %				%			+	c          C   s-   x& t  r( t d ƒ }  |  d k r |  Sq Wd  S(   Ns„   
            Do you want to keep the first or last duplicate instance?
            Enter "first" or "last" to continue.
            t   firstt   last(   R#   R$   (   R   R   (   t   first_or_last(    (    s]   /tmp/pip-unpacked-wheel-a0M10Y/django_extensions/management/commands/merge_model_instances.pyt   keep_first_or_last_instanceD   s
    		c          C   s`   g  }  xS t  j ƒ  D]E } x< | j j ƒ  D]+ \ } } t | t ƒ r) |  j | ƒ q) q) Wq W|  S(   s6   Return a list of all GenericForeignKeys in all models.(   R    R   t   __dict__t   itemst
   isinstanceR   t   append(   t   generic_fieldsR   t
   field_nameR   (    (    s]   /tmp/pip-unpacked-wheel-a0M10Y/django_extensions/management/commands/merge_model_instances.pyt   get_generic_fieldsN   s    t   Commandc           B   s2   e  Z d  Z e d „  ƒ Z e j ƒ  d „  ƒ Z RS(   sÉ  
        Removes duplicate model instances based on a specified
        model and field name(s).

        Makes sure that any OneToOne, ForeignKey, or ManyToMany relationships
        attached to a deleted model(s) get reattached to the remaining model.

        Based on the following:
        https://djangosnippets.org/snippets/2283/
        https://stackoverflow.com/a/41291137/2532070
        https://gist.github.com/edelvalle/01886b6f79ba0c4dce66
    c         O   sL  t  ƒ  } t | ƒ } t ƒ  } d } x| j j ƒ  D]} i  } x1 | D]) }	 | j |	 ƒ }
 | j i |
 |	 6ƒ qG Wy | j j |   Wq4 | j k
 r5| j j	 |   } | d k rÝ | j
 ƒ  } | j d | j ƒ } n0 | d k r| j ƒ  } | j d | j ƒ } n  |  j | | ƒ \ } } } | | 7} q4 Xq4 Wd j | ƒ GHd  S(   Ni    R#   t   pkR$   s(   Successfully deleted {} model instances.(   R   R"   R&   t   objectst   allt   __getattribute__t   updatet   gett   MultipleObjectsReturnedt   filterR#   t   excludeR/   R$   t   merge_model_instancest   format(   t   selft   argst   optionsR   t   field_namesR%   t   total_deleted_objects_countt   instancet   kwargsR,   t   instance_field_valuet	   instancest   primary_objectt   alias_objectst   deleted_objectst   deleted_objects_count(    (    s]   /tmp/pip-unpacked-wheel-a0M10Y/django_extensions/management/commands/merge_model_instances.pyt   handlef   s.    			c         C   s[  t  ƒ  } t t d „  | j j ƒ  ƒ ƒ } t t d „  | ƒ ƒ } t t d „  | ƒ ƒ } g  } d } xå| D]Ý} xö | D]î }	 |	 j }
 t | |
 ƒ } xÍ | j ƒ  D]¿ } y0 t | |
 ƒ j | ƒ t | |
 ƒ j	 | ƒ Wq¥ t
 k
 rct | |
 ƒ j } i | |	 j ƒ  6| |	 j ƒ  6} | j j |   } x2 | D]& } t | |	 j ƒ  | ƒ | j ƒ  q6Wq¥ Xq¥ Wqz Wx| D]} | j rÝ| j ƒ  }
 t | |
 ƒ } x× | j ƒ  D], } | j j } t | | | ƒ | j ƒ  qªWqs| j sï| j rs| j }
 t | |
 ƒ } t | |
 ƒ } | d k r?t | |
 | ƒ | j ƒ  qw| j rw|  j j d j | | j ƒ ƒ | j ƒ  qwqsqsWx€ | D]x } i  } | j ƒ  | | j <| j | ƒ | | j <| j  j j |   } x+ | D]# } t | | j | ƒ | j ƒ  qÓWq‚W| j rm | | g 7} |  j j d j | | j ƒ ƒ | j ƒ  | d 7} qm qm W| | | f S(   sÙ   
        Merge several model instances into one, the `primary_object`.
        Use this function to merge model objects and migrate all of the related
        fields from the alias objects the primary object.
        c         S   s   |  j  t k S(   N(   t   is_relationR   (   t   x(    (    s]   /tmp/pip-unpacked-wheel-a0M10Y/django_extensions/management/commands/merge_model_instances.pyt   <lambda>Ž   t    c         S   s   |  j  t k S(   N(   t   many_to_manyR   (   RI   (    (    s]   /tmp/pip-unpacked-wheel-a0M10Y/django_extensions/management/commands/merge_model_instances.pyRJ   ’   RK   c         S   s   |  j  t k S(   N(   RL   R   (   RI   (    (    s]   /tmp/pip-unpacked-wheel-a0M10Y/django_extensions/management/commands/merge_model_instances.pyRJ   •   RK   i    s   Deleted {} with id {}
i   N(!   R-   R   R6   R   R   R   t   getattrR1   t   removet   addt   AttributeErrort   throught   m2m_reverse_field_namet   m2m_field_nameR0   t   setattrt   savet   one_to_manyt   get_accessor_nameR   t
   one_to_onet   many_to_onet   Nonet   stdoutt   writeR9   t   idt   deletet   _get_pk_valt   fk_fieldt   get_content_typet   ct_fieldR   (   R:   RC   RD   R+   t   related_fieldst   many_to_many_fieldsRE   RF   t   alias_objectt   many_to_many_fieldt   alias_varnamet   related_objectst   objt   through_modelR@   t   through_model_instancesR?   t   related_fieldR,   t   related_objectt   primary_related_objectR   t   filter_kwargst   generic_related_object(    (    s]   /tmp/pip-unpacked-wheel-a0M10Y/django_extensions/management/commands/merge_model_instances.pyR8   ƒ   s€    							
(   R   t
   __module__t   helpR   RG   R   t   atomicR8   (    (    (    s]   /tmp/pip-unpacked-wheel-a0M10Y/django_extensions/management/commands/merge_model_instances.pyR.   X   s   N(   t   django.appsR    t"   django.contrib.contenttypes.fieldsR   t   django.core.managementR   t	   django.dbR   t"   django_extensions.management.utilsR   R   R"   R&   R-   R.   (    (    (    s]   /tmp/pip-unpacked-wheel-a0M10Y/django_extensions/management/commands/merge_model_instances.pyt   <module>   s   		/	
	
