a
    xd                     @   s|   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	m
Z
 dd Zdd	 Zd
d ZdddZdddZdd ZdS )    N)transaction)ManyToManyField)model_to_dict)AlternativeManagerErrorNotHistoricalModelErrorc           
      C   s   i }t | }| jd ur| n|}t|}dd |jjjD }| jjD ]D}|j|vrRqBt| |j}|jdu r||d ur|||j< qB|||j< qB|j	f i |
d }	||	_|	  d S )Nc                 S   s   g | ]
}|j qS  )attname.0fieldr   r   L/var/www/html/Ranjet/env/lib/python3.9/site-packages/simple_history/utils.py
<listcomp>       z(update_change_reason.<locals>.<listcomp>Tz-history_date)typeidget_history_manager_for_modelmodel_metafieldsr   getattrZprimary_keyfilterZorder_byfirstZhistory_change_reasonsave)
instancereasonattrsr   managerhistoryZhistory_fieldsr   valuerecordr   r   r   update_change_reason   s     

r    c                 C   s:   z| j j}W n" ty.   tdj| dY n0 t| |S )z1Return the history manager for a given app model.z+Cannot find a historical model for {model}.r   )r   Z simple_history_manager_attributeAttributeErrorr   formatr   )r   Zmanager_namer   r   r   r       s    

r   c                 C   s
   t | jS )z/Return the history model for a given app model.)r   r   r!   r   r   r   get_history_model_for_model+   s    r$   Fc              	   C   s  dd |j  D }t|}|j}	d}
tjddJ |	j| ||d}|rn|d jrn|snd}
|j|||||d W d	   n1 s0    Y  |
rg }tjdd` |D ]6}t	t
d
d t||d }||	j
f i |7 }q|j|||||d W d	   n1 s
0    Y  |}|S )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
    :return: List of objs with IDs
    c                 S   s   g | ]}t |tr|jqS r   )
isinstancer   namer	   r   r   r   r   L   s   
z,bulk_create_with_history.<locals>.<listcomp>TFZ	savepoint)
batch_sizeignore_conflictsr   )r(   default_userdefault_change_reasondefault_dateNc                 S   s   | d d uS )N   r   )xr   r   r   <lambda>h   r   z*bulk_create_with_history.<locals>.<lambda>)exclude)r   Z
get_fieldsr   _default_managerr   atomicZbulk_createpkbulk_history_createdictr   r   items)objsr   r(   r)   r*   r+   r,   Zexclude_fieldshistory_managermodel_managerZsecond_transaction_requiredZobjs_with_idZobj_listobj
attributesr   r   r   bulk_create_with_history0   sN    $&r<   c           
   	   C   sz   t |}|p|j}	|	j|ur$tdtjdd6 |	j| ||d |j| |d|||d W d   n1 sl0    Y  dS )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
    :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
    z/The given manager does not belong to the model.Fr'   )r(   T)r(   updater*   r+   r,   N)r   r1   r   r   r   r2   Zbulk_updater4   )
r7   r   r   r(   r*   r+   r,   r   r8   r9   r   r   r   bulk_update_with_historyx   s    

r>   c                 C   s   t | drt| dS d S )NZ_change_reason)hasattrr   )r:   r   r   r   get_change_reason_from_object   s    

r@   )NFNNN)NNNNN)warningsZdjangoZ	django.dbr   Zdjango.db.modelsr   Zdjango.forms.modelsr   Zsimple_history.exceptionsr   r   r    r   r$   r<   r>   r@   r   r   r   r   <module>   s*        
L     
+