3
gH                 @   s.  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ddddddddddddddg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$d% Z)G d&d' d'Z*d0d)d*Z+d+d, Z,d-d. Z-dS )1z
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'Bas van Oostveen <v.oostveen@gmail.com>zQAntonio Cavedoni <https://cavedoni.com/>Stefano J. Attardi <https://attardi.org/>Z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blueZorangegreenyellowZgreyZpurplec             C   sZ   | sg S t | tttfr| S d| krFtjj| rFdd t| j D S dd | j	dD S )N,c             S   s   g | ]}|j  qS  )strip).0er   r   c/var/www/tester-filtro-web/env/lib/python3.6/site-packages/django_extensions/management/modelviz.py
<listcomp>E   s    z&parse_file_or_list.<locals>.<listcomp>c             S   s   g | ]}|j  qS r   )r   )r   r   r   r   r   r   F   s    )

isinstancelisttuplesetospathisfileopen	readlinessplit)argr   r   r   parse_file_or_list?   s    r)   c               @   s   e Zd Zdd Zdd Zd0ddZdd	 Zd1ddZdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ ZdS )2
ModelGraphc             K   sF  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d k	rt| j t|jdd| _t|jdd| _|jdd| _|jd| _|jdd| _| jr0dd tj D | _n|| _|jd| _d S )Ncli_optionsdisable_fieldsFdisable_abstract_fieldsinclude_models all_applicationsZ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             S   s   g | ]
}|j qS r   )label)r   appr   r   r   r   f   s    z'ModelGraph.__init__.<locals>.<listcomp>rankdir)graphsgetr+   r,   r-   r)   r.   r0   use_subgraphr1   r2   r3   r4   r5   r6   activate_languager7   r8   r9   r:   r;   r   Zget_app_configs
app_labelsr>   )selfrC   kwargsr   r   r   __init__J   s6    

zModelGraph.__init__c             C   s   | j   g }x&| jD ]}|jdd |d D  qW xN| jD ]D}x>|d D ]2}x,|d D ] }|d k	rX|d |krXd|d< qXW qJW q<W d S )Nc             S   s   g | ]}|d  qS )namer   )r   r   r   r   r   r   p   s    z2ModelGraph.generate_graph_data.<locals>.<listcomp>models	relationstargetF
needs_node)process_appsr?   extend)rD   Znodesgraphmodelrelationr   r   r   generate_graph_datak   s    zModelGraph.generate_graph_dataFc             C   s   t j j }|jd| j| j| j| j| jd}|rdd | jD }xD|D ]<}x6|d D ]*}|j	d x|d D ]}|j	d qlW qTW qFW ||d	< n
| j|d	< |S )
Nz%Y-%m-%d %H:%M)Z
created_atr+   r,   r-   rA   r>   c             S   s   g | ]}|j  qS r   )flatten)r   contextr   r   r   r      s    z-ModelGraph.get_graph_data.<locals>.<listcomp>rH   rO   fieldsfieldr?   )
datetimenowstrftimer+   r,   r-   rA   r>   r?   pop)rD   Zas_jsonrW   
graph_datar?   rS   Z
model_dataZ
field_datar   r   r   get_graph_datay   s"    





zModelGraph.get_graph_datac          	      s   | j r( jr(t j}|j r.|j }n j}t j}t t	t
frX|dj jj7 }  j|| jt fdd|D t t jdS )Nz ({0})c             3   s   | ]} j |j kV  qd S )N)Zcreation_counter)r   Zabstract_field)rU   r   r   	<genexpr>   s   z,ModelGraph.add_attributes.<locals>.<genexpr>)rU   rG   r<   typeblankabstractrP   primary_key)r1   verbose_namer   islower
capitalizerG   r]   __name__r   r   r   formatremote_field
field_namer^   anyr   r`   )rD   rU   abstract_fieldsr<   tr   )rU   r   add_attributes   s$    



zModelGraph.add_attributesr/   Nc             C   s2  | j r(|jr(t|j}|j r.|j }n|j}t|drn|j }| j r^|j r^|jddj }dj	|t|}| j
rxd}t|jjtr|jjdkr|j}qd|jjkr|jjjdd\}}	n|jjj}|jj}	tj||	}n|jj}|rd	j	|dd |}| j||||}
|
|d
 kr.| j|
d r.|
S d S )Nrelated_query_name_ z{} ({})r/   rD   .   z[{}, color={}]rI   rJ   )r1   ra   r   rb   rc   rG   hasattrrl   replacere   r9   r   rf   rO   strr'   _meta	app_labelr   Z	get_modelget_relation_context	use_model)rD   rU   rO   extrascolorr<   rl   target_modelrv   
model_name_relr   r   r   add_relation   s4    



zModelGraph.add_relationc             C   s6   g }x |D ]}|dd |j D 7 }q
W tt|}|S )Nc             S   s"   g | ]}t |d r|jjr|qS )ru   )rr   ru   r_   )r   abstract_modelr   r   r   r      s    z2ModelGraph.get_abstract_models.<locals>.<listcomp>)	__bases__r   r!   )rD   	appmodelsabstract_modelsappmodelr   r   r   get_abstract_models   s    
zModelGraph.get_abstract_modelsc             C   s,   t d|j d|j d|jjdd g dS )Nz"%s"z%sz
cluster_%sro   rm   )rG   app_nameZcluster_app_namerH   )r   rG   rs   )rD   r=   r   r   r   get_app_context   s
    zModelGraph.get_app_contextc             C   s0   | j rdd |jjD }ndd |jjD }|S )Nc             S   s   g | ]}|qS r   r   )r   rU   r   r   r   r      s    z6ModelGraph.get_appmodel_attributes.<locals>.<listcomp>c             S   s   g | ]}t |ts|qS r   )r   r   )r   rU   r   r   r   r      s    )r3   ru   local_fields)rD   r   
attributesr   r   r   get_appmodel_attributes   s    z"ModelGraph.get_appmodel_attributesc             C   s   dd |j D S )Nc             S   s$   g | ]}t |d r|jjr|jqS )ru   )rr   ru   r_   rd   )r   r   r   r   r   r      s    z5ModelGraph.get_appmodel_abstracts.<locals>.<listcomp>)r   )rD   r   r   r   r   get_appmodel_abstracts   s    z!ModelGraph.get_appmodel_abstractsc             C   sN   ||j jdd|j|g g d}| jr>|jjr>t|jj|d< n|d |d< |S )Nro   rm   )rO   r   rG   	abstractsrT   rI   r<   rG   )
__module__rs   rd   r1   ru   ra   r   )rD   r   appmodel_abstractsrS   r   r   r   get_appmodel_context   s    zModelGraph.get_appmodel_contextc             C   sH   g }x>|j D ]4}t|dr|jjr|j|jj |j| j| qW |S )Nru   )r   rr   ru   r_   rM   rT   get_bases_abstract_fields)rD   cZ_abstract_fieldsr   r   r   r   r     s    z$ModelGraph.get_bases_abstract_fieldsc             C   sN   d}|j jrd}|j jrd}|d7 }| jr.d}|jjdd|jdd|d	d
dS )Nzmulti-tabler_   proxyz\ninheritancer/   ro   rm   r2   z+[arrowhead=empty, arrowtail=none, dir=both]T)
target_apprJ   r]   rG   r<   arrowsrK   )ru   r_   r   r9   r   rs   rd   )rD   r   parentr<   r   r   r   get_inheritance_context  s    z"ModelGraph.get_inheritance_contextc             C   s   t |j }|S )N)r   
get_models)rD   r=   r   r   r   r   r   !  s    zModelGraph.get_modelsc             C   s(   |j jdd|jt|j|j||ddS )Nro   rm   T)r   rJ   r]   rG   r<   r   rK   )r   rs   rd   r]   rG   )rD   r{   rU   r<   ry   r   r   r   rw   %  s    zModelGraph.get_relation_contextc             C   s<   |j  }| j|s|r"||kr"|S |d j| j|| |S )NrT   )copy
skip_fieldappendrk   )rD   rU   rO   pkri   newmodelr   r   r   process_attributes0  s
    zModelGraph.process_attributesc             C   s  x~| j D ]r}tj|}|s q
| j|}| j|}| j|}|| }x |D ]}| j|jjsdqN| j	|}| j
|}| j||}	| j|}
|jj}|r|jj r||
kr|	d j| j|| x|
D ]}| j||	||}	qW | jr| j|	}	x|jjD ]}| j||	|}	qW x|jjD ]}| j||	}	qW | jrXx|jD ]}| j|||	}	q@W |d j|	 qNW |d r
| jj| q
W d S )NrT   rH   )rC   r   Zget_app_configr   r   r   rx   ru   Zobject_namer   r   r   r   r   r_   r   rk   r   r5   sort_model_fieldsr   process_local_fieldsZlocal_many_to_manyprocess_local_many_to_manyr2   r   process_parentr?   )rD   rv   r=   Z	app_graphZ
app_modelsr   r   r   ri   rO   r   r   rU   r   r   r   r   rL   7  s@    








zModelGraph.process_appsc             C   s   |j  }|jjds&||ks&| j|r*|S d }| jrZt|ttfrZt|j	dd }t
j|}t|trv| j||d|}n(t|tr| j||dj| j|}nd }|d k	r|d j| |S )NZ_ptr_idZ	on_deletez*[arrowhead=none, arrowtail=none, dir=both]z([arrowhead=none, arrowtail={}, dir=both]rI   )r   Zattnameendswithr   r;   r   r   r   getattrrf   ON_DELETE_COLORSr@   r~   re   r:   r   )rD   rU   rO   ri   r   rz   Zfield_on_deleterP   r   r   r   r   c  s*    


zModelGraph.process_local_fieldsc             C   s   |j  }| j|r|S d }t|trZt|jjdrv|jjjjrv| j	||dj
| j| j}nt|trv| j	||td}|d k	r|d j| |S )Nru   z%[arrowhead={} arrowtail={}, dir=both]z>[style="dotted", arrowhead=normal, arrowtail=normal, dir=both]rI   )r   r   r   r   rr   rf   Zthroughru   Zauto_createdr~   re   r:   r
   r   r   )rD   rU   rO   r   rP   r   r   r   r     s     


z%ModelGraph.process_local_many_to_manyc             C   sJ   |j  }t|drF| j||}||d krF| j|d rF|d j| |S )Nru   rI   rJ   )r   rr   r   rx   r   )rD   r   r   rO   r   r}   r   r   r   r     s    
zModelGraph.process_parentc             C   s$   |j  }t|d dd d|d< |S )NrT   c             S   s   | d  | d  | d fS )Nr`   rP   r<   r   )rU   r   r   r   <lambda>  s    z.ModelGraph.sort_model_fields.<locals>.<lambda>)key)r   sorted)rD   rO   r   r   r   r   r     s    zModelGraph.sort_model_fieldsc             C   st   | j r6x.| j D ]$}d|jdd }tj||rdS qW | jrlx.| jD ]$}d|jdd }tj||rDdS qDW | 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.   rs   researchr8   )rD   r|   Zmodel_patternr   r   r   rx     s    zModelGraph.use_modelc             C   sV   | j r2| jr"|jr"|j| j kr"dS |j| j kr2dS | jrRt|tttt	t
tfsRdS dS )NTF)r7   r1   ra   rG   r4   r   r   r   r   r   r   r	   )rD   rU   r   r   r   r     s    zModelGraph.skip_field)F)r/   N)rd   r   __qualname__rF   rQ   r[   rk   r~   r   r   r   r   r   r   r   r   rw   r   rL   r   r   r   r   rx   r   r   r   r   r   r*   I   s,   !

'
	,	r*   *django_extensions/graph_models/digraph.dotc             C   sZ   t |trtj|}t |t r@t|do4t |jt r@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   rt   r   Zget_templater   rr   r   	Exceptionr   rR   render)rZ   r   r   dotr   r   r   generate_dot  s    

$
r   c              O   s   t | |}|j  |j S )N)r*   rQ   r[   )argsrE   	generatorr   r   r   rQ     s    
rQ   c             C   s   t g ||d}|j| S )N)r.   r8   )r*   rx   )rO   r.   r8   r   r   r   r   rx     s    rx   )r   )r   ).__doc__rV   r"   r   Zdjango.appsr   Zdjango.db.modelsr   Zdjango.db.models.fields.relatedr   r   r   r   Z'django.db.models.fields.reverse_relatedr   r	   Z"django.contrib.contenttypes.fieldsr
   Zdjango.templater   r   r   Zdjango.utils.encodingr   Zdjango.utils.safestringr   Zdjango.utils.translationr   rB   __version____license__
__author__Z__contributors__ZCASCADEZPROTECTZSET_NULLZSET_DEFAULTZSETZ
DO_NOTHINGZRESTRICTr   r)   r*   r   rQ   rx   r   r   r   r   <module>	   sX   

   
