
    Nwg%                         d dl mZ d dlmZmZmZmZmZ d dlm	Z	 d dl
mZmZ d Zd Zd Zd Zd	 Zd
edefdZd
edefdZ	 	 	 	 	 	 ddZ	 	 	 	 	 	 ddZd Zy)    )transaction)Case
ForeignKeyManyToManyFieldQWhen)model_to_dict)AlternativeManagerErrorNotHistoricalModelErrorc                 8   i }t        |       }| j                  | n|}t        |      }|j                  j                  j
                  D cg c]  }|j                   }}| j                  j
                  D ]W  }|j                  |vrt        | |j                        }|j                  du r|9|||j                  <   I|||j                  <   Y  |j                  di |j                  d      j                         }	||	_        |	j                          y c c}w )NTz-history_date )typepkget_history_manager_for_modelmodel_metafieldsattnamegetattrprimary_keyfilterorder_byfirsthistory_change_reasonsave)
instancereasonattrsr   managerhistoryfieldhistory_fieldsvaluerecords
             K/var/www/horilla/myenv/lib/python3.12/site-packages/simple_history/utils.pyupdate_change_reasonr&      s    ENE"++1huG+G4G181D1D1K1KLemmLNL&& )==.%--0$ ',emm$#(E%-- ) W^^$e$--o>DDFF#)F 
KKM Ms   Dc                     	 | j                   j                  }t	        | |      S # t        $ r t        d|  d      w xY w)z1Return the history manager for a given app model.z#Cannot find a historical model for .)r    simple_history_manager_attributeAttributeErrorr   r   )r   manager_names     r%   r   r      sO    V{{CC 5,''  V%(KE7RS&TUUVs   $ =c           	          t        | j                        } t        | j                        j                  di |t	        | |      iS )zL
    Return the history manager, based on an existing history instance.
    r   )get_app_model_primary_key_nameinstance_typer   r   r   )history_instancekey_names     r%    get_history_manager_from_historyr1   &   sL     ..>.L.LMHO()9)G)GHOO W-x8
9     c                 ,    t        |       j                  S )z/Return the history model for a given app model.)r   r   r   s    r%   get_history_model_for_modelr5   0   s    (/555r2   c                     t        | j                  j                  t              r#| j                  j                  j                  dz   S | j                  j                  j                  S )z2Return the primary key name for a given app model._id)
isinstancer   r   r   namer4   s    r%   r-   r-   5   sA    %++..*-{{~~""U**;;>>r2   	m2m_fieldreturnc                 "    | j                         S )a1  
    Returns the field name of an M2M field's through model that corresponds to the model
    the M2M field is defined on.

    E.g. for a ``votes`` M2M field on a ``Poll`` model that references a ``Vote`` model
    (and with a default-generated through model), this function would return ``"poll"``.
    )m2m_field_namer:   s    r%   get_m2m_field_namer?   <   s     ##%%r2   c                 "    | j                         S )a.  
    Returns the field name of an M2M field's through model that corresponds to the model
    the M2M field references.

    E.g. for a ``votes`` M2M field on a ``Poll`` model that references a ``Vote`` model
    (and with a default-generated through model), this function would return ``"vote"``.
    )m2m_reverse_field_namer>   s    r%   get_m2m_reverse_field_namerB   H   s     ++--r2   Nc                 |   |j                   j                         D cg c]  }t        |t              r|j                    }	}t        |      }
|j                  }d}t        j                  d      5  |j                  | ||      }|r*|d   j                  r|sd}|
j                  ||||||       ddd       |rt        j                  d      5  d}g }t              D ]f  \  }}t        t        d t        ||		      j!                                     }t#        di |}|r||z  n|}|j%                  t'        di |d
|i       h |r/t)        |j                  |      j+                  t-        |             ng }|
j                  ||||||       ddd       }S c c}w # 1 sw Y   xY w# 1 sw Y   xY w)a  
    Bulk create the objects specified by objs while also bulk creating
    their history (all in one transaction).
    Because of not providing primary key attribute after bulk_create on any DB except
    Postgres (https://docs.djangoproject.com/en/2.2/ref/models/querysets/#bulk-create)
    Divide this process on two transactions for other DB's
    :param objs: List of objs (not yet saved to the db) of type model
    :param model: Model class that should be created
    :param batch_size: Number of objects that should be created in each batch
    :param default_user: Optional user to specify as the history_user in each historical
        record
    :param default_change_reason: Optional change reason to specify as the change_reason
        in each historical record
    :param default_date: Optional date to specify as the history_date in each historical
        record
    :param custom_historical_attrs: Optional dict of field `name`:`value` to specify
        values for custom fields
    :return: List of objs with IDs
    TF	savepoint)
batch_sizeignore_conflictsr   )rF   default_userdefault_change_reasondefault_datecustom_historical_attrsNc                     | d   d uS )N   r   )xs    r%   <lambda>z*bulk_create_with_history.<locals>.<lambda>   s    !A$d"2 r2   )excludethenr   )r   
get_fieldsr8   r   r9   r   _default_managerr   atomicbulk_creater   bulk_history_create	enumeratedictr   r	   itemsr   appendr   listr   r   )objsr   rF   rG   rH   rI   rJ   rK   r!   exclude_fieldshistory_managermodel_managersecond_transaction_requiredobjs_with_idcumulative_filterobj_when_listiobj
attributesqobj_lists                        r%   bulk_create_with_historyri   T   s   B [[++-e_- 	

N 
 4E:O**M"&			e	, $00Z:J 1 
 LO..7G*/'//%)&;)(? 0  #%0 $	 !%M#L1 A3!2%c>BHHJ
 O
O?P%6%:VW! $$T%?J%?Q%?@A*   !(():;DDm,   //%)&;)(? 0 ;$	J  } $	 $	s   #F!1AF&CF2&F/2F;c	           
      (   t        |      }	|xs |j                  }
|
j                  |urt        d      t	        j
                  d      5  |sd}n|
j                  | ||      }|	j                  | |d||||       ddd       |S # 1 sw Y   S xY w)	a=  
    Bulk update the objects specified by objs while also bulk creating
    their history (all in one transaction).
    :param objs: List of objs of type model to be updated
    :param model: Model class that should be updated
    :param fields: The fields that are updated. If empty, no model objects will be
        changed, but history records will still be created.
    :param batch_size: Number of objects that should be updated in each batch
    :param default_user: Optional user to specify as the history_user in each historical
        record
    :param default_change_reason: Optional change reason to specify as the change_reason
        in each historical record
    :param default_date: Optional date to specify as the history_date in each historical
        record
    :param manager: Optional model manager to use for the model instead of the default
        manager
    :param custom_historical_attrs: Optional dict of field `name`:`value` to specify
        values for custom fields
    :return: The number of model rows updated, not including any history objects
    z/The given manager does not belong to the model.FrD   r   )rF   T)rF   updaterH   rI   rJ   rK   N)r   rS   r   r
   r   rT   bulk_updaterV   )r\   r   r   rF   rH   rI   rJ   r   rK   r^   r_   rows_updateds               r%   bulk_update_with_historyrn      s    > 4E:O5u55M%'%&WXX			e	, 
 L(44f 5 L 	++!%"7%$; 	, 	

& '
& s   2BBc                 4    t        | d      rt        | d      S y )N_change_reason)hasattrr   )re   s    r%   get_change_reason_from_objectrr      s    s$%s,--r2   )NFNNNN)NNNNNN)	django.dbr   django.db.modelsr   r   r   r   r   django.forms.modelsr	   simple_history.exceptionsr
   r   r&   r   r1   r5   r-   strr?   rB   ri   rn   rr   r   r2   r%   <module>rx      s    ! G G - V*(6
	&/ 	&c 	&	./ 	.c 	.  ]H  7tr2   