U
     hf6                     @   s(  d Z ddlZddlmZ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 ddlmZ ddlmZmZ dd	lmZ dd
lmZ ddlmZmZmZmZmZmZ eeZ G dd dej!Z"G dd dej#Z$G dd dej!Z%G dd de$Z&G dd de%Z'G dd de%Z(G dd de%Z)dS )aV  
Enterprise-Ready Model Managers Module

This module provides custom model managers that extend Django's default
manager functionality with enterprise-level features including caching,
filtering, searching, and performance optimizations.

Features:
- Base managers with common query patterns
- Caching managers for performance optimization
- Search and filtering capabilities
- Soft delete management
- Audit trail management
- Performance monitoring and optimization
- Bulk operations with validation
- Advanced querying methods

Author: Focus Development Team
Version: 2.0.0
License: Proprietary
    N)datetime	timedelta)OptionalListDictAnyUnion)settings)timezone)cache)modelstransaction)get_user_model)ValidationError)QCountAvgSumMaxMinc                       s8   e Zd ZdZ fddZ fddZ fddZ  ZS )ActiveManagerz
    Custom manager that excludes soft deleted records by default.
    
    This manager automatically filters out records where is_deleted=True,
    providing a clean interface for working with active records only.
    c                    s   t   jddS )z
        Return queryset excluding soft deleted records.
        
        Returns:
            QuerySet: All objects where is_deleted=False
        F
is_deletedsuperget_querysetfilterself	__class__ //var/www/html/Focus/src/apps/common/managers.pyr   0   s    zActiveManager.get_querysetc                    s
   t   S )z
        Return queryset including soft deleted records.
        
        Returns:
            QuerySet: All objects including soft deleted ones
        )r   r   r   r   r!   r"   with_deleted9   s    zActiveManager.with_deletedc                    s   t   jddS )z
        Return queryset with only soft deleted records.
        
        Returns:
            QuerySet: Only objects where is_deleted=True
        Tr   r   r   r   r!   r"   deleted_onlyB   s    zActiveManager.deleted_only)__name__
__module____qualname____doc__r   r#   r$   __classcell__r!   r!   r   r"   r   (   s   		r   c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 ZdedddZ	dedddZ
dd ZedddZdeee dddZdd Zdd ZdS ) BaseQuerySetz
    Base QuerySet with common filtering and optimization methods.
    
    This QuerySet provides standard filtering capabilities and
    performance optimizations that are commonly needed across
    different models in the application.
    c                 C   s   | j ddS )Return only active objects.T	is_activer   r   r!   r!   r"   activeU   s    zBaseQuerySet.activec                 C   s   | j ddS )Return only inactive objects.Fr,   r.   r   r!   r!   r"   inactiveY   s    zBaseQuerySet.inactivec                 C   s   | j ddS )Return only published objects.Tis_publishedr.   r   r!   r!   r"   	published]   s    zBaseQuerySet.publishedc                 C   s   | j ddS )z Return only unpublished objects.Fr3   r.   r   r!   r!   r"   unpublisheda   s    zBaseQuerySet.unpublished   daysc                 C   s   t  t|d }| j|dS )*Return objects created in the last N days.r8   )created_at__gter
   nowr   r   r   r9   cutoff_dater!   r!   r"   recente   s    zBaseQuerySet.recentc                 C   s   t  t|d }| j|dS )z!Return objects older than N days.r8   )Zcreated_at__ltr<   r>   r!   r!   r"   
older_thanj   s    zBaseQuerySet.older_thanc                 C   s   | j |dS )*Return objects created by a specific user.
created_byr.   r   userr!   r!   r"   by_usero   s    zBaseQuerySet.by_userstatusc                 C   s   | j |dS )z&Return objects with a specific status.rH   r.   )r   rI   r!   r!   r"   	by_statuss   s    zBaseQuerySet.by_statusNqueryfieldsc                 C   s>   |r|s| S t  }|D ]}|t f | d|iO }q| |S )z
        Perform text search across specified fields.
        
        Args:
            query: Search query string
            fields: List of fields to search in
            
        Returns:
            Filtered QuerySet
        Z__icontains)r   r   )r   rL   rM   Zsearch_filterfieldr!   r!   r"   searchw   s    zBaseQuerySet.searchc                 C   s   | j tdtjddS )z'Add common annotations to the queryset.id
created_at)total_countZcreated_date)annotater   r   	functions	TruncDater   r!   r!   r"   with_annotations   s    
zBaseQuerySet.with_annotationsc                 C   s   |    S )z+Apply common optimizations to the queryset.)select_relatedprefetch_relatedr   r!   r!   r"   	optimized   s    zBaseQuerySet.optimized)r7   )r7   )N)r%   r&   r'   r(   r/   r1   r5   r6   intr@   rA   rG   strrJ   r   rO   rV   rY   r!   r!   r!   r"   r*   L   s   r*   c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 ZdedddZ	dd Z
deee dddZdeej eedddZdd ZedddZdS ) BaseManagerz
    Base manager class providing common functionality.
    
    This manager provides standard methods and optimizations
    that are commonly needed across different models.
    c                 C   s   t | j| jdS )zReturn the base queryset.using)r*   model_dbr   r!   r!   r"   r      s    zBaseManager.get_querysetc                 C   s   |    S )r+   )r   r/   r   r!   r!   r"   r/      s    zBaseManager.activec                 C   s   |    S )r0   )r   r1   r   r!   r!   r"   r1      s    zBaseManager.inactivec                 C   s   |    S )r2   )r   r5   r   r!   r!   r"   r5      s    zBaseManager.publishedr7   r8   c                 C   s   |   |S )r:   )r   r@   )r   r9   r!   r!   r"   r@      s    zBaseManager.recentc                 C   s   |   |S )rB   )r   rG   rE   r!   r!   r"   rG      s    zBaseManager.by_userNrK   c                 C   s   |   ||S )z,Perform text search across specified fields.)r   rO   )r   rL   rM   r!   r!   r"   rO      s    zBaseManager.searchF)objs
batch_sizeignore_conflictsc                 C   s"   |D ]}|   q| j|||dS )a?  
        Bulk create objects with validation.
        
        Args:
            objs: List of model instances to create
            batch_size: Number of objects to create in each batch
            ignore_conflicts: Whether to ignore conflicts
            
        Returns:
            List of created objects
        )rb   rc   )
full_cleanbulk_create)r   ra   rb   rc   objr!   r!   r"   bulk_create_with_validation   s    
z'BaseManager.bulk_create_with_validationc                 K   s.   z| j f |W S  | jjk
r(   Y dS X dS )z
        Get an object or return None if not found.
        
        Args:
            **kwargs: Lookup parameters
            
        Returns:
            Model instance or None
        N)getr_   DoesNotExistr   kwargsr!   r!   r"   get_or_none   s    
zBaseManager.get_or_none)returnc                 K   s   | j f | S )z
        Check if an object exists with given parameters.
        
        Args:
            **kwargs: Lookup parameters
            
        Returns:
            Boolean indicating existence
        )r   existsrj   r!   r!   r"   	exists_by   s    
zBaseManager.exists_by)r7   )N)NF)r%   r&   r'   r(   r   r/   r1   r5   rZ   r@   rG   r[   r   rO   r   Modelboolrg   rl   ro   r!   r!   r!   r"   r\      s"     r\   c                       s0   e Zd ZdZdd Z fddZdd Z  ZS )SoftDeleteQuerySetz
    QuerySet for models with soft delete functionality.
    
    This QuerySet automatically excludes soft-deleted objects
    from standard queries while providing methods to access
    deleted objects when needed.
    c                 C   s   | j dt dS )z/Perform soft delete on all objects in queryset.T)r   
deleted_at)updater
   r=   r   r!   r!   r"   delete   s    zSoftDeleteQuerySet.deletec                    s
   t   S ))Permanently delete objects from database.)r   ru   r   r   r!   r"   hard_delete  s    zSoftDeleteQuerySet.hard_deletec                 C   s   | j ddddS )zRestore soft-deleted objects.FN)r   rs   
deleted_by)rt   r   r!   r!   r"   restore  s
    zSoftDeleteQuerySet.restore)r%   r&   r'   r(   ru   rw   ry   r)   r!   r!   r   r"   rr      s   rr   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )SoftDeleteManagerz
    Manager for models with soft delete functionality.
    
    This manager automatically excludes soft-deleted objects from
    standard queries while providing methods to access deleted objects.
    c                 C   s   t | j| jdjddS )z4Override to exclude soft-deleted objects by default.r]   Fr   rr   r_   r`   r   r   r!   r!   r"   r     s    zSoftDeleteManager.get_querysetc                 C   s   t | j| jdjddS )z!Return only soft-deleted objects.r]   Tr   r{   r   r!   r!   r"   deleted  s    zSoftDeleteManager.deletedc                 C   s   t | j| jdS )z/Return all objects including soft-deleted ones.r]   )rr   r_   r`   r   r!   r!   r"   r#     s    zSoftDeleteManager.with_deletedc                 C   s   t | j| jd S )rv   r]   )rr   r_   r`   rw   r   r!   r!   r"   rw   #  s    zSoftDeleteManager.hard_deleteN)r%   r&   r'   r(   r   r|   r#   rw   r!   r!   r!   r"   rz     s
   rz   c                   @   sV   e Zd ZdZdZdZeedddZeddd	Zedd
dZ	deedddZ
dS )CachedManagerz
    Manager with caching capabilities for improved performance.
    
    This manager provides automatic caching of frequently accessed
    objects and query results to improve application performance.
    i  Zcached_manager)keyrm   c                 C   s   | j  d| jjj d| S )z%Generate cache key for the given key.:)cache_prefixr_   _metalabel)r   r~   r!   r!   r"   _get_cache_key3  s    zCachedManager._get_cache_key)	cache_keyc                 K   s^   |  |}t|}|dkrZz | jf |}t||| j W n | jjk
rX   d}Y nX |S )z
        Get an object from cache or database.
        
        Args:
            cache_key: Key to use for caching
            **kwargs: Lookup parameters
            
        Returns:
            Model instance or None
        N)r   r   rh   setcache_timeoutr_   ri   )r   r   rk   full_cache_keyrf   r!   r!   r"   
get_cached7  s    


zCachedManager.get_cachedc                 C   s   |  |}t| dS )zInvalidate cached object.N)r   r   ru   )r   r   r   r!   r!   r"   invalidate_cacheN  s    
zCachedManager.invalidate_cacheN)r   queryset_methodc                 K   sT   |  |}t|}|dkrP| jf |}|r8t|| }t|}t||| j |S )a&  
        Get a list of objects from cache or database.
        
        Args:
            cache_key: Key to use for caching
            queryset_method: Method to call on queryset
            **kwargs: Filter parameters
            
        Returns:
            List of model instances
        N)r   r   rh   r   getattrlistr   r   )r   r   r   rk   r   objectsquerysetr!   r!   r"   get_cached_listS  s    

zCachedManager.get_cached_list)N)r%   r&   r'   r(   r   r   r[   r   r   r   r   r!   r!   r!   r"   r}   (  s   r}   c                   @   sr   e Zd ZdZdeejeeeddddZeddd	Z	d
d Z
ejdddZeedddZdedddZdS )AuditManagerz
    Manager for audit log functionality.
    
    This manager provides methods for creating and querying
    audit log entries with proper filtering and optimization.
    NZAuditLog)actionrf   changes
ip_address
user_agentrm   c           	      C   sT   ddl m} |||pi ||d}|rH||j|t|jt|d | jf |S )a  
        Create an audit log entry.
        
        Args:
            action: Action performed
            user: User who performed the action
            obj: Object affected by the action
            changes: Dictionary of changes made
            ip_address: IP address of the user
            user_agent: User agent string
            
        Returns:
            Created AuditLog instance
        r   ContentType)r   rD   r   r   r   )object_type	object_idobject_repr)"django.contrib.contenttypes.modelsr   rt   r   get_for_modelr[   pkcreate)	r   r   rF   rf   r   r   r   r   Z
audit_datar!   r!   r"   
log_actiont  s    
zAuditManager.log_actionr   c                 C   s   | j |dS )z(Return audit logs for a specific action.r   r.   )r   r   r!   r!   r"   	by_action  s    zAuditManager.by_actionc                 C   s   | j |dS )z&Return audit logs for a specific user.rC   r.   rE   r!   r!   r"   rG     s    zAuditManager.by_user)rf   c                 C   s,   ddl m} |j|}| j|t|jdS )z(Return audit logs for a specific object.r   r   )r   r   )r   r   r   r   r   r[   r   )r   rf   r   content_typer!   r!   r"   	by_object  s    zAuditManager.by_object)
start_dateend_datec                 C   s   | j ||gdS )z&Return audit logs within a date range.)Zcreated_at__ranger.   )r   r   r   r!   r!   r"   by_date_range  s    zAuditManager.by_date_ranger7   r8   c                 C   sV   t  t|d }| j||ddjtddd}tdd |D t	||d	S )
z
        Get user activity summary for the last N days.
        
        Args:
            user: User to get activity for
            days: Number of days to look back
            
        Returns:
            Dictionary with activity statistics
        r8   )rD   r;   r   rP   )countz-countc                 s   s   | ]}|d  V  qdS )r   Nr!   ).0itemr!   r!   r"   	<genexpr>  s     z5AuditManager.user_activity_summary.<locals>.<genexpr>)Ztotal_actionsZactions_by_typeZperiod_days)
r
   r=   r   r   valuesrS   r   order_bysumr   )r   rF   r9   r?   Zactivityr!   r!   r"   user_activity_summary  s    z"AuditManager.user_activity_summary)NNNN)r7   )r%   r&   r'   r(   r[   r   rp   r   r   r   rG   r   r   r   rZ   r   r!   r!   r!   r"   r   l  s           $r   )*r(   loggingr   r   typingr   r   r   r   r   django.confr	   django.utilsr
   django.core.cacher   	django.dbr   r   django.contrib.authr   django.core.exceptionsr   django.db.modelsr   r   r   r   r   r   	getLoggerr%   loggerManagerr   QuerySetr*   r\   rr   rz   r}   r   r!   r!   r!   r"   <module>   s$    
$K[D