
    khZL                     T   d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	m
Z
mZmZ ddlmZmZ ddlmZ ddlmZmZmZ dd	lmZ dd
lmZ ddlmZ dZdZdZg dZ ej!        dej"        dej#        dej$        dej%        dej&        dej'        diZ(d Z) G d d          Z*ddZ+d Z,d Z-dS )z
modelviz.py - DOT file generator for Django Models

Based on:
  Django model to DOT (Graphviz) converter
  by Antonio Cavedoni <antonio@cavedoni.org>
  Adapted to be used with django-extensions
    N)apps)deletion)
ForeignKeyManyToManyFieldOneToOneFieldRelatedField)OneToOneRelManyToOneRel)GenericRelation)ContextTemplateloader)	force_str)	mark_safe)activatez1.1Python)z'Bas van Oostveen <v.oostveen@gmail.com>)zQAntonio Cavedoni <https://cavedoni.com/>Stefano J. Attardi <https://attardi.org/>limodouzCarlo C8E Mironz Andre Campos <cahenan@gmail.com>z#Justin Findlay <jfindlay@gmail.com>z&Alexander Houben <alexander@houben.ch>z Joern Hees <gitdev@joernhees.de>z%Kevin Cherepski <cherepski@gmail.com>z&Jose Tomas Tocino <theom3ga@gmail.com>z#Adam Dobrawy <naczelnik@jawnosc.tk>z6Mikkel Munch Mortensen <https://www.detfalskested.dk/>z+Andrzej Bistram <andrzej.bistram@gmail.com>z%Daniel Lipsitt <danlipsitt@gmail.com>z%Florian Anceau <flow.gunso@gmail.com>redblueorangegreenyellowgreypurplec                 ,   | sg S t          | t          t          t          f          r| S d| vrJt          j                            |           r+d t          |                                           D             S d | 	                    d          D             S )N,c                 6    g | ]}|                                 S  strip.0es     \/var/www/histauto/venv/lib/python3.11/site-packages/django_extensions/management/modelviz.py
<listcomp>z&parse_file_or_list.<locals>.<listcomp>H   s     999a		999    c                 6    g | ]}|                                 S r   r   r!   s     r$   r%   z&parse_file_or_list.<locals>.<listcomp>I   s     ...!AGGII...r&   )

isinstancelisttuplesetospathisfileopen	readlinessplit)args    r$   parse_file_or_listr3   B   s     	#eS)** 

#~~"'..--~99499#6#6#8#89999..syy~~....r&   c                       e Zd Zd Zd ZddZd ZddZd	 Zd
 Z	d Z
d Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZdS )
ModelGraphc                 ,   g | _         |                    dd           | _        |                    dd          | _        |                    dd          | _        t          |                    dd                    | _        |                    dd          | _        |                    dd          | _        |                    d	d          | _	        |                    d
d          | _
        |                    dd          | _        |                    dd          | _        |                    dd          | _        |                    dd           | _        | j        t          | j                   t          |                    dd                    | _        t          |                    dd                    | _        |                    dd          | _        |                    d          | _        |                    dd          | _        | j        r#d t+          j                    D             | _        n|| _        |                    d          | _        |                    dd          | _        |                    d          | _        d S )Ncli_optionsdisable_fieldsFdisable_abstract_fieldsinclude_models all_applicationsgroup_modelsverbose_namesinheritanceTrelations_as_fieldsrelation_fields_onlysort_fieldslanguageexclude_columnsexclude_modelshide_edge_labelsarrow_shapecolor_code_deletionsc                     g | ]	}|j         
S r   )label)r"   apps     r$   r%   z'ModelGraph.__init__.<locals>.<listcomp>c   s    KKKSsyKKKr&   rankdirdisplay_field_choicesordering)graphsgetr7   r8   r9   r3   r:   r<   use_subgraphr>   r?   r@   rA   rB   rC   activate_languagerD   rE   rF   rG   rH   r   get_app_configs
app_labelsrL   rM   rN   )selfrT   kwargss      r$   __init__zModelGraph.__init__M   s*   !::mT::$jj)95AA'-zz2KU'S'S$0<Lb1Q1QRR &

+=u E E"JJ~u==#ZZ??!::mT::#)::.CT#J#J $*JJ/Eu$M$M!!::mT::

:t44=$dm,,,1&**=NPR2S2STT0<Lb1Q1QRR &

+=u E E!::m44$*JJ/Eu$M$M!  	)KKD4H4J4JKKKDOO(DOzz),,%+ZZ0G%O%O"

:..r&   c                     |                                   g }| j        D ]'}|                    d |d         D                        (| j        D ])}|d         D ]}|d         D ]}||d         |v rd|d<   *d S )Nc                     g | ]
}|d          S )namer   r!   s     r$   r%   z2ModelGraph.generate_graph_data.<locals>.<listcomp>o   s    ===!F)===r&   models	relationstargetF
needs_node)process_appsrO   extend)rU   nodesgraphmodelrelations        r$   generate_graph_datazModelGraph.generate_graph_dataj   s    [ 	? 	?ELL==U8_===>>>>[ 	; 	;Ex ; ; %k 2 ; ;H+#H-665:H\2;;	; 	;r&   Fc           	         t           j                                         }|                    d          | j        | j        | j        | j        | j        | j        | j	        d}|r\d | j
        D             }|D ]B}|d         D ]7}|                    d           |d         D ]}|                    d           8C||d<   n
| j
        |d<   |S )	Nz%Y-%m-%d %H:%M)
created_atr7   r8   r9   rM   rQ   rL   rN   c                 6    g | ]}|                                 S r   )flatten)r"   contexts     r$   r%   z-ModelGraph.get_graph_data.<locals>.<listcomp>   s"    CCCGgoo''CCCr&   r[   rc   fieldsfieldrO   )datetimenowstrftimer7   r8   r9   rM   rQ   rL   rN   rO   pop)rU   as_jsonrn   
graph_datarO   rj   
model_data
field_datas           r$   get_graph_datazModelGraph.get_graph_datax   s   ##%%,,'788+"1'+'C%)%? -|	
 	

  	/ DCt{CCCF! 0 0")("3 0 0JNN7+++&0&: 0 0
"w////00 $*Jx  #';Jx r&   c           
      4   | j         rDj        r=t          j                  }|                                r|                                }nj        }t                    j        }t          t          t          f          r"|d                    j        j                  z  }| j        r'j         d j        D             }t!          |          }j        ||j        t%          fd|D                       t          t&                    j        dS )Nz ({0})c                     h | ]\  }}|S r   r   )r"   c_s      r$   	<setcomp>z,ModelGraph.add_attributes.<locals>.<setcomp>   s    333TQq333r&   c              3   8   K   | ]}j         |j         k    V  d S N)creation_counter)r"   abstract_fieldrl   s     r$   	<genexpr>z,ModelGraph.add_attributes.<locals>.<genexpr>   sB        " &.*II     r&   )rl   rZ   rJ   typeblankabstractrd   primary_key)r>   verbose_namer   islower
capitalizerZ   r   __name__r(   r   r   formatremote_field
field_namerM   choicesstrr   anyr   r   )rU   rl   abstract_fieldsrJ   tr   s    `    r$   add_attributeszModelGraph.add_attributes   s1    	%"4 	e011E}} +((**JEKK emZ899 	@!3!>???A% 	%-*C33U]333GGA J[    &5     #5,77 ,
 
 	
r&   r;   Nc                    | j         rD|j        r=t          |j                  }|                                r|                                }n|j        }t          |d          rz|                                }| j         r<|                                r(|                    dd                                          }d	                    |t          |                    }| j
        rd}t          |j        j        t                    r}|j        j        dk    r|j        }nqd|j        j        v r$|j        j                            dd          \  }}	n|j        j        j        }|j        j        }	t%          j        ||	          }n|j        j        }|rd		                    |dd
         |          }|                     ||||          }
|
|d         vr|                     |
d                   r|
S d S d S )Nrelated_query_namery    z{} ({})r;   rU   .   z[{}, color={}]r\   r]   )r>   r   r   r   r   rZ   hasattrr   replacer   rF   r(   r   rc   r   r1   _meta	app_labelr   	get_modelget_relation_context	use_model)rU   rl   rc   extrascolorrJ   r   target_modelr   
model_name_rels              r$   add_relationzModelGraph.add_relation   s    	%"4 	e011E}} +((**JE 5.// 	K!&!9!9!;!;! W&8&@&@&B&B W%7%?%?S%I%I%T%T%V%V"$$UI6H,I,IJJE  	E e(.44 	4!'611${%,222,1,>,D,J,J3PQ,R,R)Izz % 1 ;I!&!3!9J#~iDD -3L 	B%,,VAbD\5AAF((ueVLLu[)))dnnT(^.L.L)K *)))r&   c                 t    g }|D ]}|d |j         D             z  }t          t          |                    }|S )Nc                 J    g | ] }t          |d           |j        j        |!S r   )r   r   r   r"   abstract_models     r$   r%   z2ModelGraph.get_abstract_models.<locals>.<listcomp>   sI          ">733  9G8L8U      r&   )	__bases__r)   r+   )rU   	appmodelsabstract_modelsappmodels       r$   get_abstract_modelszModelGraph.get_abstract_models   s^    ! 	 	H    &.&8      OO
 s?3344r&   c           	          t          d|j        z  d|j        z  d|j                            dd          z  g d          S )Nz"%s"z%sz
cluster_%sr   ry   )rZ   app_namecluster_app_namer[   )r   rZ   r   )rU   rK   s     r$   get_app_contextzModelGraph.get_app_context   sN    ) 38O$0383C3CC3M3M$M	 
 
 	
r&   c                 n    | j         rd |j        j        D             }nd |j        j        D             }|S )Nc                     g | ]}|S r   r   r"   rl   s     r$   r%   z6ModelGraph.get_appmodel_attributes.<locals>.<listcomp>   s    IIIE%IIIr&   c                 <    g | ]}t          |t                    |S r   )r(   r   r   s     r$   r%   z6ModelGraph.get_appmodel_attributes.<locals>.<listcomp>   s8       !%66  r&   )r@   r   local_fields)rU   r   
attributess      r$   get_appmodel_attributesz"ModelGraph.get_appmodel_attributes   sR    # 		IIX^-HIIIJJ %^8  J
 r&   c                 $    d |j         D             S )Nc                 T    g | ]%}t          |d           |j        j        |j        &S r   )r   r   r   r   r   s     r$   r%   z5ModelGraph.get_appmodel_abstracts.<locals>.<listcomp>   sL     
 
 
~w//
 5C4H4Q
#
 
 
r&   )r   )rU   r   s     r$   get_appmodel_abstractsz!ModelGraph.get_appmodel_abstracts   s&    
 
"*"4
 
 
 	
r&   c                     ||j                             dd          |j        |g g d}| j        r)|j        j        rt          |j        j                  |d<   n|d         |d<   |S )Nr   ry   )rc   r   rZ   	abstractsrk   r\   rJ   rZ   )
__module__r   r   r>   r   r   r   )rU   r   appmodel_abstractsrj   s       r$   get_appmodel_contextzModelGraph.get_appmodel_context  s|     +33C==%+
 
  	/(."= 	/()DEEGG&vGGr&   c                     g }|j         D ]e}t          |d          rS|j        j        rG|                    |j        j                   |                    |                     |                     f|S )Nr   )r   r   r   r   r`   rk   get_bases_abstract_fields)rU   rx   _abstract_fieldsr#   s       r$   r   z$ModelGraph.get_bases_abstract_fields  s|     	K 	KAq'"" Kqw'7 K ''777 ''(F(Fq(I(IJJJr&   c                     d}|j         j        rd}|j         j        rd}|dz  }| j        rd}|j                            dd          |j        dd|d	d
dS )Nzmulti-tabler   proxyz\ninheritancer;   r   ry   r?   z+[arrowhead=empty, arrowtail=none, dir=both]T
target_appr]   r   rZ   rJ   arrowsr^   )r   r   r   rF   r   r   r   )rU   r   parentrJ   s       r$   get_inheritance_contextz"ModelGraph.get_inheritance_context  s    <  	E> 	E!!  	E +33C==o!!C
 
 	
r&   c                 H    t          |                                          }|S r|   )r)   
get_models)rU   rK   r   s      r$   r   zModelGraph.get_models.  s    ))**	r&   c                     |j                             dd          |j        t          |          j        |j        ||ddS )Nr   ry   Tr   )r   r   r   r   rZ   )rU   r   rl   rJ   r   s        r$   r   zModelGraph.get_relation_context2  sG    &199#sCC"+KK(J
 
 	
r&   c                     |                                 }|                     |          s|r||k    r|S |d                             |                     ||                     |S )Nrk   )copy
skip_fieldappendr   )rU   rl   rc   pkr   newmodels         r$   process_attributeszModelGraph.process_attributes=  se    ::<<??5!! 	R 	ERKKO!!$"5"5e_"M"MNNNr&   c           	      8   | j         D ]}t          j        |          }|s|                     |          }|                     |          }|                     |          }||z   }|D ]}|                     |j        j                  s#| 	                    |          }| 
                    |          }|                     ||          }	|                     |          }
|j        j        }|r?|j        j        s3||
v r/|	d                             |                     ||                     |
D ]}|                     ||	||          }	| j        r|                     |	          }	|j        j        D ]}|                     ||	|          }	|j        j        D ]}|                     ||	          }	| j        r!|j        D ]}|                     |||	          }	|d                             |	           |d         r| j                            |           d S )Nrk   r[   )rT   r   get_app_configr   r   r   r   r   object_namer   r   r   r   r   r   r   r   r   rB   sort_model_fieldsr   process_local_fieldslocal_many_to_manyprocess_local_many_to_manyr?   r   process_parentrO   )rU   r   rK   	app_graph
app_modelsr   r   r   r   rc   r   r   rl   r   s                 r$   r_   zModelGraph.process_appsD  sh    *	. *	.I%i00C ,,S11I--J"66zBBO(:5J& 2 2~~hn&@AA %)%@%@%J%J""&"@"@"J"J11(<NOO!99(CC
 ^& Uhn5 U"
:J:J(O**4+>+>r?+S+STTT' W WE 33E5"oVVEE# : 22599E%^8 U UE 55eUOTTEE%^> J JE ;;E5IIEE# M"*"4 M M $ 3 3FHe L L(#**51111" .""9---U*	. *	.r&   c                 h   |                                 }|j                            d          s||v s|                     |          r|S d }| j        rLt          |t          t          f          r0t          |j	        dd           }t                              |          }t          |t                    r|                     ||d|          }nHt          |t                    r1|                     ||d                    | j                  |          }nd }||d                             |           |S )N_ptr_id	on_deletez*[arrowhead=none, arrowtail=none, dir=both]z([arrowhead=none, arrowtail={}, dir=both]r\   )r   attnameendswithr   rH   r(   r   r   getattrr   ON_DELETE_COLORSrP   r   r   rG   r   )rU   rl   rc   r   r   r   field_on_deleterd   s           r$   r   zModelGraph.process_local_fieldsq  s@   ::<<M""9--	''u%% ( O$ 	:EM:;V)W)W 	:%e&8+tLLO$((99Ee]++ 	((x!Mu HH z** 	((:AA$BRSS	 HH H[!((222r&   c                    |                                 }|                     |          r|S d }t          |t                    rft	          |j        j        d          rK|j        j        j        j        r5| 	                    ||d
                    | j        | j                            }n9t          |t                    r$| 	                    ||t          d                    }||d                             |           |S )Nr   z%[arrowhead={} arrowtail={}, dir=both]z>[style="dotted", arrowhead=normal, arrowtail=normal, dir=both]r\   )r   r   r(   r   r   r   throughr   auto_createdr   r   rG   r   r   r   )rU   rl   rc   r   rd   s        r$   r   z%ModelGraph.process_local_many_to_many  s   ::<<??5!! 	Oe_-- 	*2G<<
&.4A
  ,,;BB($*:   // 	((T  H [!((222r&   c                     |                                 }t          |d          rV|                     ||          }||d         vr6|                     |d                   r|d                             |           |S )Nr   r\   r]   )r   r   r   r   r   )rU   r   r   rc   r   r   s         r$   r   zModelGraph.process_parent  s{    ::<<67## 	3//&AAD 8K000T^^DN5S5S0%,,T222r&   c                 d    |                                 }t          |d         d           |d<   |S )Nrk   c                 4    | d          | d          | d         fS )Nr   rd   rJ   r   )rl   s    r$   <lambda>z.ModelGraph.sort_model_fields.<locals>.<lambda>  s&    -((*%%g r&   )key)r   sorted)rU   rc   r   s      r$   r   zModelGraph.sort_model_fields  sA    ::<<#X 
 
 
 r&   c                    | j         r;| j         D ]3}d|                    dd          z  }t          j        ||          r dS 4| j        r;| j        D ]3}d|                    dd          z  }t          j        ||          r dS 4| j          S )z
        Decide whether to use a model, based on the model name and the lists of
        models to exclude and include.
        z^%s$*z.*TF)r:   r   researchrE   )rU   r   model_patterns      r$   r   zModelGraph.use_model  s      	 !%!4     &)>)>sD)I)I I9]J77  44   	!!%!4 ! ! &)>)>sD)I)I I9]J77 ! 55! &&&r&   c           	          | j         r.| j        r|j        r|j        | j         v rdS |j        | j         v rdS | j        r6t          |t          t          t          t          t          t          f          sdS dS )NTF)rD   r>   r   rZ   rA   r(   r   r   r   r   r	   r
   )rU   rl   s     r$   r   zModelGraph.skip_field  s     	!  e&8  %)===4zT111t$ 	#!  
 
  tur&   )F)r;   N)r   r   __qualname__rW   re   ru   r   r   r   r   r   r   r   r   r   r   r   r   r_   r   r   r   r   r   r   r   r&   r$   r5   r5   L   sk       / / /:; ; ;   8
 
 
<% % % %N	 	 	
 
 
  
 
 
  "     
 
 
&  	
 	
 	
  +. +. +.Z     D  :  
 
 
' ' '(    r&   r5   *django_extensions/graph_models/digraph.dotc                 `   t          |t                    rt          j        |          }t          |t                    s9t          |d          rt          |j        t                    st          d          t          |           	                                }|
                    |          }|S )NtemplatezyDefault Django template loader isn't used. This can lead to the incorrect template rendering. Please, check the settings.)r(   r   r   get_templater   r   r   	Exceptionr   ri   render)rr   r   rx   dots       r$   generate_dotr     s    (C   1&x00h)) 
*%%
*4X5F*Q*Q
 *
 
 	
 	
##%%A
//!

CJr&   c                  j    t          | i |}|                                 |                                S r|   )r5   re   ru   )argsrV   	generators      r$   re   re     s8    D+F++I!!#####%%%r&   c                 P    t          g ||          }|                    |           S )N)r:   rE   )r5   r   )rc   r:   rE   r  s       r$   r   r   
  s3    
>.  I u%%%r&   )r   ).__doc__rm   r,   r   django.appsr   django.db.modelsr   django.db.models.fields.relatedr   r   r   r   'django.db.models.fields.reverse_relatedr	   r
   "django.contrib.contenttypes.fieldsr   django.templater   r   r   django.utils.encodingr   django.utils.safestringr   django.utils.translationr   rR   __version____license__
__author____contributors__CASCADEPROTECTSET_NULLSET_DEFAULTSET
DO_NOTHINGRESTRICTr   r3   r5   r   re   r   r   r&   r$   <module>r     s     				 				       % % % % % %                   ? > > > > > 5 5 5 5 5 5 5 5 5 5 + + + + + + - - - - - - B B B B B B 9
   & efx'L(x / / /b b b b b b b bJ   && & && & & & &r&   