
    ]jP%                     n    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 G d
 de      Zy)    )apps)GenericForeignKey)BaseCommand)transaction)signalcommandc                      t        j                         } d}| D ]!  }t        |d|j                         |dz  }# t	        t        d            }| |dz
     }|S )N   . z=Enter the number of the model you would like to de-duplicate:)r   
get_modelsprint__name__intinput)modelsiteratormodelmodel_choicemodel_to_deduplicates        e/root/env/lib/python3.12/site-packages/django_extensions/management/commands/merge_model_instances.pyget_model_to_deduplicater   
   sd    __FH (ENN34A u\]^L!,"23    c           	         | j                   j                         D cg c]  }|j                   }}d}|D ]  }t        |d|       |dz  } d}|s3t	        t        d            }|t        d|      v rd}nt        d       |s3|dz
     g}d}|s|D cg c]	  }||vs| }	}d}|	D ]  }t        |d|       |dz  } t        d       d}|st        d       t        d	j                  |      d	z          t        d
      }
|
dk(  rd}d}nOt	        |
      t        t        dt        |	      dz               v r||	t	        |
      dz
     gz  }d}nt        d       |s|s|S c c}w c c}w )Nr	   r
   FzEEnter the number of the (first) field you would like to de-duplicate.Tz Invalid input. Please try again.zC. Done adding fields.z8You are currently deduplicating on the following fields:
z
                Enter the number of the field you would like to de-duplicate.
                If you have entered all fields, enter C to continue.
            C)
_meta
get_fieldsnamer   r   r   rangejoinlistlen)r   fieldfieldsr   	validatedfirst_fieldfields_to_deduplicatedonefavailable_fieldsadditional_fields              r   get_field_namesr+      s   &+kk&<&<&>?Uejj?F?H (E*+A I% ghi%8,,I45  $K!O45D
*?!?A
 
 % 	Eh./MH	 	&'	LM$))12T9:$ &    3& 	%&$uQ<L8MPQ8Q/R*SS%*:3?O;PST;T*U)VV% 	89  8 ! W @ 
s   E)	E."E.c                  (    	 t        d      } | dv r| S )Nz
            Do you want to keep the first or last duplicate instance?
            Enter "first" or "last" to continue.
            )firstlast)r   )first_or_lasts    r   keep_first_or_last_instancer0   D   s*    
   --   r   c                      g } t        j                         D ]F  }|j                  j                         D ]'  \  }}t	        |t
              s| j                  |       ) H | S )z6Return a list of all GenericForeignKeys in all models.)r   r   __dict__items
isinstancer   append)generic_fieldsr   
field_namer"   s       r   get_generic_fieldsr8   N   s_    N" -!&!5!5!7 	-J%!23%%e,	-- r   c                   N    e Zd ZdZed        Z ej                         d        Zy)Commanda  
        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                    t               }t        |      }t               }d}|j                  j	                         D ]L  }i }|D ]&  }	|j                  |	      }
|j                  |	|
i       ( 	  |j                  j                  di | N t        dj!                  |             y # |j                  $ r  |j                  j                  di |}|dk(  r-|j                         }|j                  |j                        }n1|dk(  r,|j                         }|j                  |j                        }| j                        \  }}}||z  }Y w xY w)Nr   r-   )pkr.   z(Successfully deleted {} model instances. )r   r+   r0   objectsall__getattribute__updategetMultipleObjectsReturnedfilterr-   excluder<   r.   merge_model_instancesr   format)selfargsoptionsr   field_namesr/   total_deleted_objects_countinstancekwargsr7   instance_field_value	instancesprimary_objectalias_objectsdeleted_objectsdeleted_objects_counts                   r   handlezCommand.handlef   sl   (*%e,35&'#))+ 	EHF) 
'/'@'@'L$ 4 
E!!!+F+	E* 	8??@[\] 00 
E0EMM00:6:	 G+%.__%6N$-$5$59J9J$5$KM"f,%.^^%5N$-$5$59J9J$5$KMIMIcIcdr  uB  JCF1F+/DD+
Es   -B&&B)EEc           
      .   t               }t        t        d |j                  j	                                     }t        t        d |            }t        t        d |            }g }d}|D ]  }|D ]f  }	|	j
                  }
t        ||
      }|j                         D ]9  }	 t        ||
      j                  |       t        ||
      j                  |       ; h |D ]#  }|j"                  re|j%                         }
t        ||
      }|j                         D ]5  }|j&                  j
                  }t        |||       |j!                          7 u|j(                  s|j*                  s|j
                  }
t        ||
      }t        ||
      }|t        ||
|       |j!                          |j(                  s| j,                  j/                  dj1                  ||j2                               |j5                          & |D ]  }i }|j7                         ||j8                  <   |j;                  |      ||j<                  <    |j>                  j                  j                  di |}|D ])  }t        ||j
                  |       |j!                          +  |j2                  s>||gz  }| j,                  j/                  dj1                  ||j2                               |j5                          |dz  } |||fS # t        $ r t        ||
      j                  }|	j                         ||	j                         |i} |j                  j                  di |}|D ]-  }t        ||	j                         |       |j!                          / Y w xY w)z
        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                     | j                   du S NT)is_relationxs    r   <lambda>z/Command.merge_model_instances.<locals>.<lambda>   s    ammt+ r   c                     | j                   du S rX   many_to_manyrZ   s    r   r\   z/Command.merge_model_instances.<locals>.<lambda>   s    ann, r   c                     | j                   du S )NFr^   rZ   s    r   r\   z/Command.merge_model_instances.<locals>.<lambda>   s    ann- r   r   zDeleted {} with id {}
r	   r=   ) r8   r    rD   r   r   r   getattrr?   removeaddAttributeErrorthroughm2m_reverse_field_namem2m_field_namer>   setattrsaveone_to_manyget_accessor_namer"   
one_to_onemany_to_onestdoutwriterG   iddelete_get_pk_valfk_fieldget_content_typect_fieldr   )rH   rQ   rR   r6   related_fieldsmany_to_many_fieldsrS   rT   alias_objectmany_to_many_fieldalias_varnamerelated_objectsobjthrough_modelrN   through_model_instancesrM   related_fieldr7   related_objectprimary_related_objectr"   filter_kwargsgeneric_related_objects                           r   rF   zCommand.merge_model_instances   s    ,- f+  ++-/ 0 #6,n$> ? f-~? @
  !) A	+L ': ," 2 7 7"),"F*..0 ,C,m<CCCH>BB3G	,,8 "0 0 ,,$1$C$C$EM&-lM&JO.224 #%2%8%8%=%=
Z@
# #--1J1J$1$6$6M%,\=%IN-4^]-S*-5~N&++-&11))*C*J*J*N,=,=+? @&--/%0( ( 2 "0<0H0H0Jenn-050F0F|0Tenn-"<%++"5"5"<"<"M}"M.= 2*2EJJO*//122 L>1!!";"B"B ,//#3 4##%%*%CA	+F 0EEEq * , )0m(L(T(T.EEG.==?" 3O-2G2G2N2N2XQW2X/(? ,H# ( 2 A A C .0 %MMO,,s    6LBN	N	N)	r   
__module____qualname__helpr   rU   r   atomicrF   r=   r   r   r:   r:   X   sB    D ^ ^8 [ZF ZFr   r:   N)django.appsr   "django.contrib.contenttypes.fieldsr   django.core.managementr   	django.dbr   "django_extensions.management.utilsr   r   r+   r0   r8   r:   r=   r   r   <module>r      s9     @ . ! < ,!^!FFk FFr   