
    ǷiH                     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>)zOAntonio Cavedoni <http://cavedoni.com/>Stefano J. Attardi <http://attardi.org/>z(limodou <http://www.donews.net/limodou/>z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>z5Tobias Mitterdorfer <tobias.mitterdorfer97@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     ]/srv/django_bis/venv311/lib/python3.11/site-packages/django_extensions/management/modelviz.py
<listcomp>z&parse_file_or_list.<locals>.<listcomp>E   s     999a		999    c                 6    g | ]}|                                 S r   r   r    s     r#   r$   z&parse_file_or_list.<locals>.<listcomp>F   s     ...!AGGII...r%   )

isinstancelisttuplesetospathisfileopen	readlinessplit)args    r#   parse_file_or_listr2   ?   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 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>f   s    KKKSsyKKKr%   rankdir)graphsgetr6   r7   r8   r2   r9   r;   use_subgraphr=   r>   r?   r@   rA   rB   activate_languagerC   rD   rE   rF   rG   r   get_app_configs
app_labelsrK   )selfrQ   kwargss      r#   __init__zModelGraph.__init__J   s   !::mT::$jj)95AA'-zz2KU'S'S$0JJ',,
 
 !'

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

:t44=$dm,,,1JJ("-- 
  
 1JJ',,
 
 !'

+=u E E!::m44$*JJ/Eu$M$M!  	)KKD4H4J4JKKKDOO(DOzz),,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>p   s    ===!F)===r%   models	relationstargetF
needs_node)process_appsrL   extend)rR   nodesgraphmodelrelations        r#   generate_graph_datazModelGraph.generate_graph_datak   s    [ 	? 	?ELL==U8_===>>>>[ 	; 	;Ex ; ; %k 2 ; ;H+#H-665:H\2;;	; 	;r%   Fc                 |   t           j                                         }|                    d          | 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_atr6   r7   r8   rN   rK   c                 6    g | ]}|                                 S r   )flatten)r!   contexts     r#   r$   z-ModelGraph.get_graph_data.<locals>.<listcomp>   s"    CCCGgoo''CCCr%   rX   r`   fieldsfieldrL   )
datetimenowstrftimer6   r7   r8   rN   rK   rL   pop)rR   as_jsonrk   
graph_datarL   rg   
model_data
field_datas           r#   get_graph_datazModelGraph.get_graph_datay   s    ##%%,,'788+"1'+'C -|
 

  
	/CCt{CCCF! 0 0")("3 0 0JNN7+++&0&: 0 0
"w////00 $*Jx  #';Jx r%   c           
         | j         rDj        r=t          j                  }|                                r|                                }nj        }t                    j        }t          t          t          f          r"|d                    j        j                  z  }j        ||j        t          fd|D                       t          t                     j        dS )Nz ({0})c              3   8   K   | ]}j         |j         k    V  d S N)creation_counter)r!   abstract_fieldri   s     r#   	<genexpr>z,ModelGraph.add_attributes.<locals>.<genexpr>   sB        " &.*II     r%   )ri   rW   rI   typeblankabstractra   primary_key)r=   verbose_namer   islower
capitalizerW   ry   __name__r'   r   r   formatremote_field
field_namerz   anyr   r|   )rR   ri   abstract_fieldsrI   ts    `   r#   add_attributeszModelGraph.add_attributes   s     	%"4 	e011E}} +((**JEKK emZ899 	@!3!>???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_name_ z{} ({})r:   rR   .   z[{}, color={}]rY   rZ   )r=   r}   r   r~   r   rW   hasattrr   replacer   rE   r'   r   r`   strr0   _meta	app_labelr   	get_modelget_relation_context	use_model)rR   ri   r`   extrascolorrI   r   target_modelr   
model_name_rels              r#   add_relationzModelGraph.add_relation   s    	%"4 	e011E}} +((**JE 5.// 	L!&!9!9!;!;! W&8&@&@&B&B W%7%?%?S%I%I%T%T%V%V"%%eY7I-J-JKKE  	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>   sF          #1>733 8F8L8U      r%   )	__bases__r(   r*   )rR   	appmodelsabstract_modelsappmodels       r#   get_abstract_modelszModelGraph.get_abstract_models   s^    ! 	 	H    5=5G      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   r   )rW   app_namecluster_app_namerX   )r   rW   r   )rR   rJ   s     r#   get_app_contextzModelGraph.get_app_context   sN    SX%sx ,sx/?/?S/I/I I	
 
   	r%   c                 n    | j         rd |j        j        D             }nd |j        j        D             }|S )Nc                     g | ]}|S r   r   r!   ri   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>   s6     ; ; ;E$UL99;% ; ; ;r%   )r?   r   local_fields)rR   r   
attributess      r#   get_appmodel_attributesz"ModelGraph.get_appmodel_attributes   sO    # 	;IIX^-HIIIJJ; ;X^-H ; ; ;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>   sI     
 
 
(6~w//
4B4H4Q
#
 
 
r%   )r   )rR   r   s     r#   get_appmodel_abstractsz!ModelGraph.get_appmodel_abstracts   s&    
 
:B:L
 
 
 	
r%   c                     ||j                             dd          |j        |g g d}| j        r)|j        j        rt          |j        j                  |d<   n|d         |d<   |S )Nr   r   )r`   r   rW   	abstractsrh   rY   rI   rW   )
__module__r   r   r=   r   r}   r   )rR   r   appmodel_abstractsrg   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]   rh   get_bases_abstract_fields)rR   c_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   r   r>   z+[arrowhead=empty, arrowtail=none, dir=both]T
target_apprZ   ry   rW   rI   arrowsr[   )r   r{   r   rE   r   r   r   )rR   r   parentrI   s       r#   get_inheritance_contextz"ModelGraph.get_inheritance_context  s    <  	E> 	E!!  	E +33C==o!!C
 
 	
r%   c                 H    t          |                                          }|S ru   )r(   
get_models)rR   rJ   r   s      r#   r   zModelGraph.get_models!  s    ))**	r%   c                     |j                             dd          |j        t          |          j        |j        ||ddS )Nr   r   Tr   )r   r   r   ry   rW   )rR   r   ri   rI   r   s        r#   r   zModelGraph.get_relation_context%  sG    &199#sCC"+KK(J
 
 	
r%   c                     |                                 }|                     |          s|r||k    r|S |d                             |                     ||                     |S )Nrh   )copy
skip_fieldappendr   )rR   ri   r`   pkr   newmodels         r#   process_attributeszModelGraph.process_attributes0  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 )Nrh   rX   )rQ   r   get_app_configr   r   r   r   r   object_namer   r   r   r   r   r{   r   r   r   rA   sort_model_fieldsr   process_local_fieldslocal_many_to_manyprocess_local_many_to_manyr>   r   process_parentrL   )rR   r   rJ   	app_graph
app_modelsr   r   r   r   r`   r   r   ri   r   s                 r#   r\   zModelGraph.process_apps7  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---S)	. )	.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]rY   )r   attnameendswithr   rG   r'   r   r   getattrr   ON_DELETE_COLORSrM   r   r   rF   r   )rR   ri   r`   r   r   r   field_on_deletera   s           r#   r   zModelGraph.process_local_fieldsc  sD   ::<<=!!),, 	0H0HDOO\aLbLb0H O$ 	:EM:;V)W)W 	:%e&8+tLLO$((99Ee]++ 	((x!Mu HH z** 
	((:AA$   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]rY   )r   r   r'   r   r   r   throughr   auto_createdr   r   rF   r   r   r   )rR   ri   r`   r   ra   s        r#   r   z%ModelGraph.process_local_many_to_many  s   ::<<??5!! 	Oe_-- 
	Gu)17;; @R@Z@`@m ,,;BB($*:   // 	G(()  EE  ;F  ;F  G  GH[!((222r%   c                     |                                 }t          |d          rV|                     ||          }||d         vr6|                     |d                   r|d                             |           |S )Nr   rY   rZ   )r   r   r   r   r   )rR   r   r   r`   r   r   s         r#   r   zModelGraph.process_parent  sy    ::<<67## 	3//&AAD8K000T^^DN5S5S0%,,T222r%   c                 d    |                                 }t          |d         d           |d<   |S )Nrh   c                 4    | d          | d          | d         fS )Nr|   ra   rI   r   )ri   s    r#   <lambda>z.ModelGraph.sort_model_fields.<locals>.<lambda>  s7    uUbOcKcinoyizez  }B  CJ  }K  KL r%   )key)r   sorted)rR   r`   r   s      r#   r   zModelGraph.sort_model_fields  sC    ::<<#HX$6  =L  =L  M  M  M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)r9   r   researchrD   )rR   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)rC   r=   r}   rW   r@   r'   r   r   r   r   r	   r
   )rR   ri   s     r#   r   zModelGraph.skip_field  s     	!  e&8  %)===4zT111t$ 	_m\;Xde   tur%   )F)r:   N)r   r   __qualname__rT   rb   rr   r   r   r   r   r   r   r   r   r   r   r   r   r\   r   r   r   r   r   r   r   r%   r#   r4   r4   I   sk       - - -B; ; ;   2
 
 
6% % % %N      
 
 
  "     
 
 
&  	
 	
 	
  *. *. *.X  >  (    
' ' '(    r%   r4   *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   rf   render)ro   r   r   dots       r#   generate_dotr     s    (C   1&x00h)) 778Z3P3P 7U_`h`qs{U|U| 7 6 7 7 	7 	
##%%A
//!

CJr%   c                  j    t          | i |}|                                 |                                S ru   )r4   rb   rr   )argsrS   	generators      r#   rb   rb     s8    D+F++I!!#####%%%r%   c                 P    t          g ||          }|                    |           S )N)r9   rD   )r4   r   )r`   r9   rD   r   s       r#   r   r     s*    2n^\\\Iu%%%r%   )r   ).__doc__rj   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   rO   __version____license__
__author____contributors__CASCADEPROTECTSET_NULLSET_DEFAULTSET
DO_NOTHINGRESTRICTr   r2   r4   r   rb   r   r   r%   r#   <module>r     s     				 				       % % % % % %                   ? > > > > > 5 5 5 5 5 5 5 5 5 5 + + + + + + - - - - - - B B B B B B 7
   ( efx'L(x / / /| | | | | | | |~   & & && & & & &r%   