
    jgH                        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jB                  dejD                  dejF                  dejH                  dejJ                  dejL                  dejN                  diZ(d Z) G d d      Z*ddZ+d Z,d Z-y)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>z5Tobias Mitterdorfer <tobias.mitterdorfer97@gmail.com>redblueorangegreenyellowgreypurplec                 b   | sg S t        | t        t        t        f      r| S d| vrTt        j
                  j                  |       r5t        |       j                         D cg c]  }|j                          c}S | j                  d      D cg c]  }|j                          c}S c c}w c c}w )N,)
isinstancelisttuplesetospathisfileopen	readlinesstripsplit)arges     `/var/www/html/Stanley/venv/lib/python3.12/site-packages/django_extensions/management/modelviz.pyparse_file_or_listr+   ?   s    	#eS)*

#~"''..-#'9#6#6#89#8a	#899"yy~.~!AGGI~.. :.s    B'B,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y)
ModelGraphc                 V   g | _         |j                  dd       | _        |j                  dd      | _        |j                  dd      | _        t        |j                  dd            | _        |j                  dd      | _        |j                  dd      | _        |j                  d	d      | _	        |j                  d
d      | _
        |j                  dd      | _        |j                  dd      | _        |j                  dd      | _        |j                  dd       | _        | j                  t        | j                         t        |j                  dd            | _        t        |j                  dd            | _        |j                  dd      | _        |j                  d      | _        |j                  dd      | _        | j                  r2t+        j,                         D cg c]  }|j.                   c}| _        n|| _        |j                  d      | _        y c c}w )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_deletionsrankdir)graphsgetr/   r0   r1   r+   r2   r4   use_subgraphr6   r7   r8   r9   r:   r;   activate_languager<   r=   r>   r?   r@   r   get_app_configslabel
app_labelsrA   )selfrH   kwargsapps       r*   __init__zModelGraph.__init__J   s   !::mT:$jj)95A'-zz2KU'S$0JJ',
 !'

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

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

+=u E!::m4$*JJ/Eu$M!  484H4H4JK4JSsyy4JKDO(DOzz), Ls   ,H&c                    | j                          g }| j                  D ]'  }|j                  |d   D cg c]  }|d   	 c}       ) | j                  D ]&  }|d   D ]  }|d   D ]  }||d   |v sd|d<     ( y c c}w )Nmodelsname	relationstargetF
needs_node)process_appsrB   extend)rI   nodesgraphr)   modelrelations         r*   generate_graph_datazModelGraph.generate_graph_datak   s    [[ELLU8_=_!F)_=> ! [[Ex %k 2H+#H-65:H\2 !3 ) ! >s   A?
c                    t         j                   j                         }|j                  d      | j                  | j                  | j
                  | j                  | j                  d}|rk| j                  D cg c]  }|j                          }}|D ]8  }|d   D ].  }|j                  d       |d   D ]  }|j                  d        0 : ||d<   |S | j                  |d<   |S c c}w )Nz%Y-%m-%d %H:%M)
created_atr/   r0   r1   rD   rA   rN   rW   fieldsfieldrB   )datetimenowstrftimer/   r0   r1   rD   rA   rB   flattenpop)rI   as_jsonr_   
graph_datacontextrB   
model_data
field_datas           r*   get_graph_datazModelGraph.get_graph_datay   s    ##%,,'78++"11'+'C'C --||

 7;{{C{Ggoo'{FC!")("3JNN7+&0&:
"w/ '; #4 "
 $*Jx   $(;;Jx  Ds   9C'c           
         | j                   rBj                  r6t        j                        }|j                         r|j	                         }nj
                  }t              j                  }t        t        t        f      r(|dj                  j                  j                        z  }j
                  ||j                  t        fd|D              t        t               j"                  dS )Nz ({0})c              3   P   K   | ]  }j                   |j                   k(    y wN)creation_counter).0abstract_fieldr]   s     r*   	<genexpr>z,ModelGraph.add_attributes.<locals>.<genexpr>   s*      &5N &&.*I*II&5s   #&)r]   rO   rG   typeblankabstractrX   primary_key)r6   verbose_namer   islower
capitalizerO   rp   __name__r   r   r   formatremote_field
field_namerq   anyr   rs   )rI   r]   abstract_fieldsrG   ts    `   r*   add_attributeszModelGraph.add_attributes   s    %"4"4e001E}}((*JJEK  emZ89!3!3!>!>??A JJ[[ &5  #5,7 ,,
 	
    Nc                 *   | j                   rB|j                  r6t        |j                        }|j                         r|j	                         }n|j
                  }t        |d      rg|j                         }| j                   r0|j                         r |j                  dd      j	                         }dj                  |t        |            }| j                  rd}t        |j                  j                  t              r|j                  j                  dk(  r|j                  }nd|j                  j                  v r*|j                  j                  j                  dd      \  }}	n6|j                  j                   j"                  }|j                  j                  }	t%        j&                  ||	      }n|j                  j                  }|rd	j                  |dd
 |      }| j)                  ||||      }
|
|d   vr| j+                  |
d         r|
S y y )Nrelated_query_name_ z{} ({})r3   rI   .   z[{}, color={}]rP   rQ   )r6   rt   r   ru   rv   rO   hasattrr   replacerx   r>   r   ry   rW   strr'   _meta	app_labelr   	get_modelget_relation_context	use_model)rI   r]   rW   extrascolorrG   r   target_modelr   
model_name_rels              r*   add_relationzModelGraph.add_relation   s   %"4"4e001E}}((*JJE 5./!&!9!9!;!!&8&@&@&B%7%?%?S%I%T%T%V"%%eY7I-JKE  E e((..4!!''61${{%,,222,1,>,>,D,D,J,J3PQ,R)Iz % 1 1 ; ;I!&!3!3!9!9J#~~iD --33L%,,VAb\5AF((ueVLu[))dnnT(^.LK /M)r   c           	          g }|D ]A  }||j                   D cg c]&  }t        |d      r|j                  j                  r|( c}z  }C t	        t        |            }|S c c}w Nr   )	__bases__r   r   rr   r   r    )rI   	appmodelsabstract_modelsappmodelabstract_models        r*   get_abstract_modelszModelGraph.get_abstract_models   sp    !H5=5G5G 5G>>738L8L8U8U 5G  O "
 s?34 s   +Ac           	          t        d|j                  z  d|j                  z  d|j                  j                  dd      z  g d      S )Nz"%s"z%sz
cluster_%sr   r   )rO   app_namecluster_app_namerN   )r   rO   r   )rI   rK   s     r*   get_app_contextzModelGraph.get_app_context   sG    SXX%sxx ,sxx/?/?S/I I	
  	r   c                     | j                   r%|j                  j                  D cg c]  }| }}|S |j                  j                  D cg c]  }t        |t              s| }}|S c c}w c c}w rk   )r8   r   local_fieldsr   r   )rI   r   r]   
attributess       r*   get_appmodel_attributesz"ModelGraph.get_appmodel_attributes   sw    ##-5^^-H-HI-HE%-HJI
  .6^^-H-H ;-HE$UL9  -HJ ; J;s   	A'
A,c                     |j                   D cg c]0  }t        |d      r"|j                  j                  r|j                  2 c}S c c}w r   )r   r   r   rr   rw   )rI   r   r   s      r*   get_appmodel_abstractsz!ModelGraph.get_appmodel_abstracts   sK    :B:L:L
:L~w/N4H4H4Q4Q ##:L
 	
 
s   5Ac                     ||j                   j                  dd      |j                  |g g d}| j                  r:|j                  j
                  r$t        |j                  j
                        |d<   |S |d   |d<   |S )Nr   r   )rW   r   rO   	abstractsr\   rP   rG   rO   )
__module__r   rw   r6   r   rt   r   )rI   r   appmodel_abstractsre   s       r*   get_appmodel_contextzModelGraph.get_appmodel_context   s     ++33C=%%+
 (.."="=()D)DEGG   'vGGr   c                     g }|j                   D ]k  }t        |d      s|j                  j                  s'|j	                  |j                  j
                         |j	                  | j                  |             m |S r   )r   r   r   rr   rT   r\   get_bases_abstract_fields)rI   c_abstract_fieldsr)   s       r*   r   z$ModelGraph.get_bases_abstract_fields  sc    Aq'"qww'7'7 ''7 ''(F(Fq(IJ   r   c                     d}|j                   j                  rd}|j                   j                  rd}|dz  }| j                  rd}|j                  j                  dd      |j                  dd|d	d
dS )Nzmulti-tablerr   proxyz\ninheritancer3   r   r   r7   z+[arrowhead=empty, arrowtail=none, dir=both]T
target_apprQ   rp   rO   rG   arrowsrR   )r   rr   r   r>   r   r   rw   )rI   r   parentrG   s       r*   get_inheritance_contextz"ModelGraph.get_inheritance_context  sz    <<  E>>E!!  E ++33C=oo!!C
 	
r   c                 8    t        |j                               }|S rk   )r   
get_models)rI   rK   r   s      r*   r   zModelGraph.get_models!  s    )*	r   c                     |j                   j                  dd      |j                  t        |      j                  |j                  ||ddS )Nr   r   Tr   )r   r   rw   rp   rO   )rI   r   r]   rG   r   s        r*   r   zModelGraph.get_relation_context%  sH    &1199#sC"++K((JJ
 	
r   c                     |j                         }| j                  |      s|r||k(  r|S |d   j                  | j                  ||             |S )Nr\   )copy
skip_fieldappendr~   )rI   r]   rW   pkr|   newmodels         r*   process_attributeszModelGraph.process_attributes0  sK    ::<??5!RERKO!!$"5"5e_"MNr   c           	      P   | j                   D ]  }t        j                  |      }|s| j                  |      }| j	                  |      }| j                  |      }||z   }|D ]  }| j                  |j                  j                        s*| j                  |      }| j                  |      }| j                  ||      }	| j                  |      }
|j                  j                  }|r>|j                  j                  s(||
v r$|	d   j                  | j!                  ||             |
D ]  }| j#                  ||	||      }	 | j$                  r| j'                  |	      }	|j                  j(                  D ]  }| j+                  ||	|      }	 |j                  j,                  D ]  }| j/                  ||	      }	 | j0                  r$|j2                  D ]  }| j5                  |||	      }	 |d   j                  |	        |d   s| j6                  j                  |        y )Nr\   rN   )rH   r   get_app_configr   r   r   r   r   object_namer   r   r   r   r   rr   r   r~   r   r:   sort_model_fieldsr   process_local_fieldslocal_many_to_manyprocess_local_many_to_manyr7   r   process_parentrB   )rI   r   rK   	app_graph
app_modelsr   r   r   r|   rW   r   r   r]   r   s                 r*   rS   zModelGraph.process_apps7  s   I%%i0C,,S1I-J"66zBO(:5J&~~hnn&@&@A%)%@%@%J""&"@"@"J11(<NO!99(C
 ^^&&hnn55"
:J(O**4+>+>r?+ST'E 33E5"oVE ( ## 2259E%^^88E 55eUOTE 9 &^^>>E ;;E5IE ? ##"*"4"4 $ 3 3FHe L #5 (#**51= '> """9-S )r   c                     |j                         }|j                  j                  d      s||v s| j                  |      r|S d }| j                  rBt        |t        t        f      r,t        |j                  dd       }t        j                  |      }t        |t              r| j                  ||d|      }n@t        |t              r.| j                  ||dj                  | j                        |      }nd }||d   j                  |       |S )N_ptr_id	on_deletez*[arrowhead=none, arrowtail=none, dir=both]z([arrowhead=none, arrowtail={}, dir=both]rP   )r   attnameendswithr   r@   r   r   r   getattrry   ON_DELETE_COLORSrC   r   rx   r?   r   )rI   r]   rW   r|   r   r   field_on_deleterX   s           r*   r   zModelGraph.process_local_fieldsc  s    ::<==!!),0HDOO\aLb O$$EM:;V)W%e&8&8+tLO$((9Ee]+((x!MuH z*((:AA$$ H H[!((2r   c                    |j                         }| j                  |      r|S d }t        |t              rt	        |j
                  j                  d      r|j
                  j                  j                  j                  rd| j                  ||dj                  | j                  | j                              }n,t        |t              r| j                  ||t        d            }||d   j                  |       |S )Nr   z%[arrowhead={} arrowtail={}, dir=both]z>[style="dotted", arrowhead=normal, arrowtail=normal, dir=both]rP   )r   r   r   r   r   ry   throughr   auto_createdr   rx   r?   r   r   r   )rI   r]   rW   r   rX   s        r*   r   z%ModelGraph.process_local_many_to_many  s    ::<??5!Oe_-u))117;@R@R@Z@Z@`@`@m@m,,;BB(($*:*: /(()  EE  ;F  GH[!((2r   c                     |j                         }t        |d      rA| j                  ||      }||d   vr(| j                  |d         r|d   j	                  |       |S )Nr   rP   rQ   )r   r   r   r   r   )rI   r   r   rW   r   r   s         r*   r   zModelGraph.process_parent  s]    ::<67#//&AD8K00T^^DN5S%,,T2r   c                 N    |j                         }t        |d   d       |d<   |S )Nr\   c                 "    | d    | d    | d   fS )Nrs   rX   rG    )r]   s    r*   <lambda>z.ModelGraph.sort_model_fields.<locals>.<lambda>  s5    uUbOcKcinoyizez  }B  CJ  }K  KLr   )key)r   sorted)rI   rW   r   s      r*   r   zModelGraph.sort_model_fields  s/    ::<#HX$6  =L  Mr   c                 D   | j                   r>| j                   D ]/  }d|j                  dd      z  }t        j                  ||      s/ y | j                  r>| j                  D ]/  }d|j                  dd      z  }t        j                  ||      s/ y | 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)r2   r   researchr=   )rI   r   model_patterns      r*   r   zModelGraph.use_model  s     !%!4!4 &)>)>sD)I I99]J7 "5
 !%!4!4 &)>)>sD)I I99]J7  "5
 &&&&r   c           	         | j                   rJ| j                  r%|j                  r|j                  | j                   v ry|j                  | j                   v ry| j                  r+t        |t        t        t        t        t        t        f      syy)NTF)r<   r6   rt   rO   r9   r   r   r   r   r   r	   r
   )rI   r]   s     r*   r   zModelGraph.skip_field  su    !!e&8&8%%)=)==zzT111$$_m\;Xde r   )F)r3   N)rw   r   __qualname__rL   rY   rh   r~   r   r   r   r   r   r   r   r   r   r   r   rS   r   r   r   r   r   r   r   r   r*   r-   r-   I   ss    -B;2
6%N
" 
&	
*.X>(
'(r   r-   c                 &   t        |t              rt        j                  |      }t        |t              s1t        |d      rt        |j                  t              st        d      t        |       j                         }|j                  |      }|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   ra   render)rd   r   r   dots       r*   generate_dotr     s{    (C &&x0h)78Z3PU_`h`q`qs{U| 6 7 	7 	
##%A
//!
CJr   c                  X    t        | i |}|j                          |j                         S rk   )r-   rY   rh   )argsrJ   	generators      r*   rY   rY     s,    D+F+I!!###%%r   c                 @    t        g ||      }|j                  |       S )N)r2   r=   )r-   r   )rW   r2   r=   r   s       r*   r   r     s!    2n^\Iu%%r   )z*django_extensions/graph_models/digraph.dot).__doc__r^   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   rE   __version____license__
__author____contributors__CASCADEPROTECTSET_NULLSET_DEFAULTSET
DO_NOTHINGRESTRICTr   r+   r-   r   rY   r   r   r   r*   <module>r     s     	 	  %  ? 5 5 + - B 7
 ( efx'LL(x /| |~&&r   