
    hy&                         S SK Jr  S SKJr  S SKJr  S SKJrJrJ	r	  S SK
Jr  S SKJr  SSKJr  SS	KJrJr  SS
KJrJr  SSKJrJrJrJr   " S S\R4                  5      r " S S\R4                  5      rg)    )settings)get_current_site)call_command)modelsconnectionstransaction)reverse)CloneSchema   )_check_schema_name)post_schema_syncschema_needs_to_be_sync)get_creation_fakes_migrationsget_tenant_base_schema)schema_existsget_tenant_domain_modelget_public_schema_nameget_tenant_database_aliasc                      ^  \ rS rSrSrSr Sr \R                  " SSS\	/S9r
Sr Sr / r " S S	5      rS
 rS rS rS r\S 5       rSU 4S jjrS rSS jrS rSU 4S jjr  SS jrS rS rS rSrU =r$ )TenantMixin   z,
All tenant models must inherit this class.
FT?   )
max_lengthuniquedb_index
validatorsNc                       \ rS rSrSrSrg)TenantMixin.Meta.   T N__name__
__module____qualname____firstlineno__abstract__static_attributes__r        G/var/www/html/env/lib/python3.13/site-packages/django_tenants/models.pyMetar   .       r(   r*   c                     U R                   $ N)schema_nameselfs    r)   __str__TenantMixin.__str__1   s    r(   c                     [         [        5          nU R                  R                  UR                  5        U R                  5         U $ )z
Syntax sugar which helps in celery tasks, cron jobs, and other scripts

Usage:
    with Tenant.objects.get(schema_name='test') as tenant:
        # run some code in tenant test
    # run some code in previous tenant (public probably)
)r   r   _previous_tenantappendtenantactivater0   
connections     r)   	__enter__TenantMixin.__enter__4   s:     !!:!<=
$$Z%6%67r(   c                 x    [         [        5          nUR                  U R                  R	                  5       5        g r-   )r   r   
set_tenantr4   pop)r0   exc_typeexc_valexc_tbr9   s        r)   __exit__TenantMixin.__exit__C   s-     !:!<=
d33779:r(   c                 H    [         [        5          nUR                  U 5        g)z
Syntax sugar that helps at django shell with fast tenant changing

Usage:
    Tenant.objects.get(schema_name='test').activate()
N)r   r   r=   r8   s     r)   r7   TenantMixin.activateH   s      !!:!<=
d#r(   c                 F    [         [        5          nUR                  5         g)zu
Syntax sugar, return to public schema

Usage:
    test_tenant.deactivate()
    # or simpler
    Tenant.deactivate()
N)r   r   set_schema_to_public)clsr9   s     r)   
deactivateTenantMixin.deactivateR   s     !!:!<=
'')r(   c                   > [         [        5          nU R                  R                  n[	        US5      nU(       a7  U(       a0  UR
                  [        5       :w  a  [        SUR
                  -  5      eU(       aC  U(       d<  UR
                  U R
                  [        5       4;  a  [        SUR
                  -  5      e[        TU ]$  " U0 UD6  U(       aQ  U(       aJ  U R                  (       a9   U R                  SUS9  [        R                  " [        U R                  5       S9  g U(       a(  ["        R                  " [        U R                  5       S9  g U(       df  U R                  (       aT  [%        U R
                  5      (       d9   U R                  SUS9  [        R                  " [        U R                  5       S9  g g g g ! [         a    U R!                  SS9  e f = f! [         a    U R'                  5         e f = f)Nr.   zDCan't create tenant outside the public schema. Current schema is %s.zWCan't update tenant outside it's own schema or the public schema. Current schema is %s.T)check_if_exists	verbosity)senderr6   )
force_drop)r   r   _stateaddinghasattrr.   r   	Exceptionsupersaveauto_create_schemacreate_schemar   sendr   serializable_fieldsdeleter   r   _drop_schema)r0   rM   argskwargsr9   is_new
has_schema	__class__s          r)   rU   TenantMixin.save_   s    !:!<=
##Z7
&Z%;%;?U?W%W 46@6L6LM N N:+A+A$JZJZ\r\tIu+u G(445 6 6 	d%f%&T%<%<""49"M %%[AYAYA[\ #((DD\D\D^_D33M$JZJZ<[<[""49"M %%[AYAYA[\	 =\3   t,	   !!#	s   -7G 7G  G G<c                     U $ )zWin certain cases the user model isn't serializable so you may want to only send the id r    r/   s    r)   rY   TenantMixin.serializable_fields   s    r(   c                    [         [        5          n[        US5      nU(       a<  UR                  U R                  [	        5       4;  a  [        SUR                  -  5      eU(       as  [        U R                  5      (       aX  U R                  (       d  U(       a?  U R                  5         UR                  5       nUR                  SU R                  -  5        gggg)zDrops the schemar.   zWCan't delete tenant outside it's own schema or the public schema. Current schema is %s.zDROP SCHEMA "%s" CASCADEN)r   r   rR   r.   r   rS   r   auto_drop_schemapre_dropcursorexecute)r0   rO   r9   r_   rg   s        r)   r[   TenantMixin._drop_schema   s     !:!<=
Z7
*009I9IKaKc8dd G(445 6 6 -(8(899t?T?TXbMMO&&(FNN58H8HHI Yc9:r(   c                     g)zb
This is a routine which you could override to backup the tenant schema before dropping.
:return:
Nr    r/   s    r)   rf   TenantMixin.pre_drop   s    r(   c                 F   > U R                  U5        [        TU ]  " U0 UD6$ )z\
Deletes this row. Drops the tenant's schema if the attribute
auto_drop_schema set to True.
)r[   rT   rZ   )r0   rO   r\   r]   r`   s       r)   rZ   TenantMixin.delete   s'    
 	*%w~t.v..r(   c           	         [         [        5          n[        U R                  5        UR	                  5       nU(       a  [        U R                  5      (       a  g[        5       nU(       a  U(       aH  [        5       n[        5       nUR                  XpR                  5        [        SSSU R                  SUS9  O5UR                  SU R                  -  5        [        SSU R                  SUS9  UR                  5         g)z
Creates the schema 'schema_name' for this tenant. Optionally checks if
the schema already exists before creating it. Returns true if the
schema was created, false otherwise.
Fmigrate_schemasT)r6   faker.   interactiverM   zCREATE SCHEMA "%s")r6   r.   rq   rM   N)r   r   r   r.   rg   r   r   r   r
   clone_schemar   rh   rG   )	r0   rL   sync_schemarM   r9   rg   fake_migrationsbase_schemarr   s	            r)   rW   TenantMixin.create_schema   s     !!:!<=
4++,""$}T-=-=>>7946*}))+7G7GH.$("&)-)9)9).'02 3d6F6FFG.$()-)9)9).'0	2 	'')r(   c                 v     U R                   R                  SS9nU$ ! [        5       R                   a     gf = f)z*
Returns the primary domain of the tenant
T
is_primaryN)domainsgetr   DoesNotExist)r0   domains     r)   get_primary_domainTenantMixin.get_primary_domain   s>    	\\%%%6FM&(55 		s    88c           	          UR                  5       (       a  SOSn[        U5      R                  nSR                  X0R                  SU[        U5      45      nU$ )z!
Returns the URL of this tenant.
zhttps://zhttp:// .)	is_securer   r}   joinr.   r	   )r0   request	view_name	http_typer}   urls         r)   r	   TenantMixin.reverse   sP     #*"3"3"5"5J9	!'*11ggy"2"2CASTU
r(   c                 6    [        U [        R                  5      $ )zL
Get the type of tenant. Will only work for multi type tenants
:return: str
)getattrr   MULTI_TYPE_DATABASE_FIELDr/   s    r)   get_tenant_typeTenantMixin.get_tenant_type   s    
 tX??@@r(   r    )r   )F)FTr   ) r"   r#   r$   r%   __doc__re   rV   r   	CharFieldr   r.   
domain_urldomain_subfolderr4   r*   r1   r:   rB   r7   classmethodrI   rU   rY   r[   rf   rZ   rW   r~   r	   r   r'   __classcell__r`   s   @r)   r   r      s      
 ""b/A.BDK J    ;
$ 
* 
*#JJ/ @D !(*T
A Ar(   r   c                      ^  \ rS rSrSr\R                  " SSSS9r\R                  " \	R                  SS\R                  S9r\R                  " SSS9r\R                   U 4S	 j5       r " S
 S5      rS rSrU =r$ )DomainMixin   z;
All models that store the domains must inherit this class
   T)r   r   r   rz   )r   related_name	on_delete)defaultr   c                 J  > U R                   R                  R                  U R                  SS9R	                  U R
                  S9nU R                  =(       d    UR                  5       (       + U l        U R                  (       a  UR                  SS9  [        TU ](  " U0 UD6  g )NT)r6   ry   )pkFrx   )r`   objectsfilterr6   excluder   ry   existsupdaterT   rU   )r0   r\   r]   domain_listr`   s       r)   rU   DomainMixin.save   s     nn,,334;;SW3X``dhdkdk`l//G+2D2D2F.F??%0d%f%r(   c                       \ rS rSrSrSrg)DomainMixin.Metai  Tr    Nr!   r    r(   r)   r*   r     r+   r(   r*   c                     U R                   $ r-   )r}   r/   s    r)   r1   DomainMixin.__str__  s    {{r(   rx   )r"   r#   r$   r%   r   r   r   r}   
ForeignKeyr   TENANT_MODELCASCADEr6   BooleanFieldry   r   atomicrU   r*   r1   r'   r   r   s   @r)   r   r      s     TDIFx44tR[)/9F $$TDAJ& &  r(   r   N)django.confr   django.contrib.sites.shortcutsr   django.core.managementr   	django.dbr   r   r   django.urlsr	   django_tenants.cloner
   postgresql_backend.baser   signalsr   r   utilsr   r   r   r   r   r   Modelr   r   r    r(   r)   <module>r      sN      ; / 6 6  , 7 > H l l[A&,, [A|&,, r(   