a
    ܌xdfC                     @   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mZ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dd ZG dd dZdddZdd Zd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)
ForeignKeyManyToManyFieldOneToOneFieldRelatedField)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>c                 C   sZ   | sg S t | tttfr| S d| vrFtj| rFdd t|  D S dd | 	dD S )N,c                 S   s   g | ]}|  qS  strip.0er   r   ]/var/www/html/Ranjet/env/lib/python3.9/site-packages/django_extensions/management/modelviz.py
<listcomp>5       z&parse_file_or_list.<locals>.<listcomp>c                 S   s   g | ]}|  qS r   r   r   r   r   r   r   6   r   )

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   s  g | _ |dd | _|dd| _|dd| _t|dd| _|dd| _|dd| _|d	d| _	|d
d| _
|dd| _|dd| _|dd | _| jd urt| j t|dd| _t|dd| _|dd| _|d| _| jrdd t D | _n|| _d S )Ncli_optionsdisable_fieldsFdisable_abstract_fieldsinclude_models all_applicationsZgroup_modelsverbose_namesinheritanceTrelations_as_fieldssort_fieldslanguageexclude_columnsexclude_modelshide_edge_labelsarrow_shapec                 S   s   g | ]
}|j qS r   )label)r   appr   r   r   r   T   r   z'ModelGraph.__init__.<locals>.<listcomp>)graphsgetr&   r'   r(   r$   r)   r+   use_subgraphr,   r-   r.   r/   r0   activate_languager1   r2   r3   r4   r   Zget_app_configs
app_labels)selfr;   kwargsr   r   r   __init__:   s6    




zModelGraph.__init__c                 C   sx   |    g }| jD ]}|dd |d D  q| jD ]<}|d D ].}|d D ] }|d urN|d |v rNd|d< qNqBq6d S )Nc                 S   s   g | ]}|d  qS )namer   r   r   r   r   r   ]   r   z2ModelGraph.generate_graph_data.<locals>.<listcomp>models	relationstargetF
needs_node)process_appsr7   extend)r<   nodesgraphmodelrelationr   r   r   generate_graph_dataX   s    

zModelGraph.generate_graph_dataFc                 C   s   t j  }|d| j| j| j| jd}|rdd | jD }|D ]4}|d D ]&}|d |d D ]}|d qbqLq@||d	< n
| j|d	< |S )
Nz%Y-%m-%d %H:%M)Z
created_atr&   r'   r(   r9   c                 S   s   g | ]}|  qS r   )flatten)r   contextr   r   r   r   r   r   z-ModelGraph.get_graph_data.<locals>.<listcomp>r@   rH   fieldsfieldr7   )	datetimenowstrftimer&   r'   r(   r9   r7   pop)r<   Zas_jsonrP   
graph_datar7   rL   Z
model_dataZ
field_datar   r   r   get_graph_dataf   s"    



zModelGraph.get_graph_datac              	   C   s~   | j r(|jr(t|j}| r.| }n|j}t|j}t|t	t
frX|d|jj7 }||j|||j||v t|t|jdS )Nz ({0}))rN   r?   r5   typeblankabstractrI   primary_key)r,   verbose_namer   islower
capitalizer?   rU   __name__r   r   r   formatremote_field
field_namerV   r   rX   )r<   rN   abstract_fieldsr5   tr   r   r   add_attributes~   s"    


zModelGraph.add_attributesr*   c           
      C   s  | j r(|jr(t|j}| r.| }n|j}t|drn| }| j r^| r^|dd }d	|t|}| j
rxd}t|jjtr|jjdkr|j}qd|jjv r|jjdd\}}n|jjj}|jj}t||}n|jj}| ||||}	|	|d	 vr| |	d
 r|	S d S )Nrelated_query_name_ z{} ({})r*   r<   .   rA   rB   )r,   rY   r   rZ   r[   r?   hasattrrc   replacer]   r3   r   r^   rH   strr"   _meta	app_labelr   Z	get_modelget_relation_context	use_model)
r<   rN   rH   extrasr5   rc   target_modelrl   
model_name_relr   r   r   add_relation   s0    



zModelGraph.add_relationc                 C   s2   g }|D ]}|dd |j D 7 }qtt|}|S )Nc                 S   s"   g | ]}t |d r|jjr|qS rk   )rh   rk   rW   r   Zabstract_modelr   r   r   r      s   z2ModelGraph.get_abstract_models.<locals>.<listcomp>)	__bases__r   r   )r<   	appmodelsabstract_modelsappmodelr   r   r   get_abstract_models   s    
zModelGraph.get_abstract_modelsc                 C   s,   t d|j d|j d|jdd g dS )Nz"%s"z%sz
cluster_%srf   rd   )r?   app_nameZcluster_app_namer@   )r   r?   ri   )r<   r6   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   rN   r   r   r   r      r   z6ModelGraph.get_appmodel_attributes.<locals>.<listcomp>c                 S   s   g | ]}t |ts|qS r   )r   r   r}   r   r   r   r      s   
)r.   rk   local_fields)r<   ry   
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 rt   )rh   rk   rW   r\   ru   r   r   r   r      s   z5ModelGraph.get_appmodel_abstracts.<locals>.<listcomp>)rv   )r<   ry   r   r   r   get_appmodel_abstracts   s    z!ModelGraph.get_appmodel_abstractsc                 C   sN   ||j dd|j|g g d}| jr>|jjr>t|jj|d< n|d |d< |S )Nrf   rd   )rH   r{   r?   Z	abstractsrM   rA   r5   r?   )
__module__ri   r\   r,   rk   rY   r   )r<   ry   appmodel_abstractsrL   r   r   r   get_appmodel_context   s    	zModelGraph.get_appmodel_contextc                 C   sD   g }|j D ]4}t|dr
|jjr
||jj || | q
|S )Nrk   )rv   rh   rk   rW   rE   rM   get_bases_abstract_fields)r<   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dd|jdd|d	d
dS )Nzmulti-tablerW   proxyz\ninheritancer*   rf   rd   r-   z+[arrowhead=empty, arrowtail=none, dir=both]TZ
target_apprB   rU   r?   r5   ZarrowsrC   )rk   rW   r   r3   r   ri   r\   )r<   ry   parentr5   r   r   r   get_inheritance_context   s     z"ModelGraph.get_inheritance_contextc                 C   s   t | }|S N)r   
get_models)r<   r6   rw   r   r   r   r     s    zModelGraph.get_modelsc                 C   s(   |j dd|jt|j|j||ddS )Nrf   rd   Tr   )r   ri   r\   rU   r?   )r<   rp   rN   r5   ro   r   r   r   rm     s    zModelGraph.get_relation_contextc                 C   s<   |  }| |s|r"||kr"|S |d | || |S )NrM   )copy
skip_fieldappendrb   )r<   rN   rH   pkr`   newmodelr   r   r   process_attributes  s
    zModelGraph.process_attributesc              	   C   sh  | j D ]Z}t|}|sq| |}| |}| |}|| }|D ]}| |jjs\qF| 	|}| 
|}| ||}	| |}
|jj}|r|jjs||
v r|	d | || |
D ]}| ||	||}	q| jr| |	}	|jjD ]}| ||	|}	q|jjD ]}| ||	}	q| jr>|jD ]}| |||	}	q(|d |	 qF|d r| j| qd S )NrM   r@   )r;   r   Zget_app_configr|   r   rz   rn   rk   Zobject_namer   r   r   r   r   rW   r   rb   r   r/   sort_model_fieldsr~   process_local_fieldsZlocal_many_to_manyprocess_local_many_to_manyr-   rv   process_parentr7   )r<   rl   r6   Z	app_graphZ
app_modelsrx   ry   r   r`   rH   r   r   rN   r   r   r   r   rD     s@    









zModelGraph.process_appsc                 C   s   |  }|jds&||v s&| |r*|S t|trD| ||d}n&t|trf| ||d| j	}nd }|d ur|d 
| |S )NZ_ptr_idz*[arrowhead=none, arrowtail=none, dir=both]z([arrowhead=none, arrowtail={}, dir=both]rA   )r   Zattnameendswithr   r   r   rs   r   r]   r4   r   )r<   rN   rH   r`   r   rI   r   r   r   r   I  s&    

zModelGraph.process_local_fieldsc                 C   s   |  }| |r|S d }t|trZt|jjdrv|jjjjrv| 	||d
| j| j}nt|trv| 	||td}|d ur|d | |S )Nrk   z%[arrowhead={} arrowtail={}, dir=both]z>[style="dotted", arrowhead=normal, arrowtail=normal, dir=both]rA   )r   r   r   r   rh   r^   Zthroughrk   Zauto_createdrs   r]   r4   r   r   r   )r<   rN   rH   r   rI   r   r   r   r   a  s$    


z%ModelGraph.process_local_many_to_manyc                 C   sJ   |  }t|drF| ||}||d vrF| |d rF|d | |S )Nrk   rA   rB   )r   rh   r   rn   r   )r<   r   ry   rH   r   rr   r   r   r   r   u  s    
zModelGraph.process_parentc                 C   s$   |  }t|d dd d|d< |S )NrM   c                 S   s   | d  | d  | d fS )NrX   rI   r5   r   )rN   r   r   r   <lambda>  r   z.ModelGraph.sort_model_fields.<locals>.<lambda>)key)r   sorted)r<   rH   r   r   r   r   r   ~  s    zModelGraph.sort_model_fieldsc                 C   sp   | j r4| j D ]&}d|dd }t||r dS q| jrh| jD ]&}d|dd }t||r@ dS q@| 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)   ri   researchr2   )r<   rq   Zmodel_patternr   r   r   rn     s    

zModelGraph.use_modelc                 C   s6   | j r2| jr"|jr"|j| j v r"dS |j| j v r2dS dS )NTF)r1   r,   rY   r?   )r<   rN   r   r   r   r     s    zModelGraph.skip_fieldN)F)r*   )r\   r   __qualname__r>   rJ   rT   rb   rs   rz   r|   r   r   r   r   r   r   rm   r   rD   r   r   r   r   rn   r   r   r   r   r   r%   9   s,   

$
	,	r%   *django_extensions/graph_models/digraph.dotc                 C   sV   t |trt|}t |ts<t|dr4t |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   rj   r
   Zget_templater	   rh   r   	Exceptionr   rK   render)rS   r   r   dotr   r   r   generate_dot  s    

 
r   c                  O   s   t | i |}|  | S r   )r%   rJ   rT   )argsr=   	generatorr   r   r   rJ     s    rJ   c                 C   s   t g ||d}|| S )N)r)   r2   )r%   rn   )rH   r)   r2   r   r   r   r   rn     s    rn   )r   )!__doc__rO   r   r   Zdjango.appsr   Zdjango.db.models.fields.relatedr   r   r   r   Z"django.contrib.contenttypes.fieldsr   Zdjango.templater   r	   r
   Zdjango.utils.encodingr   Zdjango.utils.safestringr   Zdjango.utils.translationr   r:   __version____license__
__author__Z__contributors__r$   r%   r   rJ   rn   r   r   r   r   <module>   s*   	
  j
