Introduction
This article will be an article which is focusing on the step to achieve a certain purpose. It is for generate an entity relationship diagram (ERD). Specifically, the entity relationship diagram (ERD) describing the database structure from a Django application. Actually, this article is referring the steps for generating entity relationship diagram (ERD) from another article. It is an article exist in this link. Before going in to the step for generating the entity relationship diagram, just prepare several things before. In other words, there will be some sort of preparation which exist in the following description as follows :
Preparation
-
Off course, it need python. Just check several of the articles exist for installing Python in Microsoft Windows as an example in this context. Among those articles are How to Install Python in Microsoft Windows, How to Install Python 3.10 in Microsoft Windows, How to Install Python in Microsoft Windows 11.
-
After installing python, the next step is to install ‘pip’ tools for installing Django. There is article exist for describing the process of ‘pip’ tool installation, such as How to Install pip in Microsoft Windows and How to Install pip in Microsoft Windows 11
-
Next step, create a python virtual environment for containing the necessary python tools and libraries for the Django project. For a further reference, just read article How to Create a Python Virtual Environment with a specific version of Python in Microsoft Windows.
-
Soon after ‘pip’ tool exist in the local device, just install Django. Whether it is in a normal default environment or an active isolated python virtual environment. As a reference, just check article How to Install Django in Microsoft Windows in order to install it using ‘pip’ tool.
-
Moving forward, just create a Django project after successfully. Check How to Create Django Project in Microsoft Windows using Command Line for more information.
-
Another preparation, maybe just create a Django application which is an optional step. Although for generation the entity relationship diagram (ERD) context, it is fine without any of it. Since it already has a Django project exist. For creating a Django application, access as an additional info in How to Create a Django Application inside a Django Project in Microsoft Windows.
How to Generate ERD
So, this section will focus on the steps for generating entity relationship diagram (ERD). After the preparation above, just follow all the steps in that article. Below, there are steps as an attempt to generate an entity relationship diagram (ERD) :
-
First of all, install an important library for generating the diagram. In this context, it is a python library with the name of ‘graphviz’. Below is the execution of the process :
(env) C:\django\myproject>python -m pip install graphviz Collecting graphviz Using cached graphviz-0.20.1-py3-none-any.whl (47 kB) Installing collected packages: graphviz Successfully installed graphviz-0.20.1 [notice] A new release of pip available: 22.2.2 -> 22.3 [notice] To update, run: python.exe -m pip install --upgrade pip (env) C:\django\myproject>
-
Well, if necessary, continue by updating ‘pip’ tool as follows :
(env) C:\django\myproject>python -m pip install --upgrade pip Requirement already satisfied: pip in c:\python\python310\lib\site-packages (22.2.2) Collecting pip Downloading pip-22.3-py3-none-any.whl (2.1 MB) ---------------------------------------- 2.1/2.1 MB 55.0 kB/s eta 0:00:00 Installing collected packages: pip Attempting uninstall: pip Found existing installation: pip 22.2.2 Uninstalling pip-22.2.2: Successfully uninstalled pip-22.2.2 WARNING: The scripts pip.exe, pip3.10.exe and pip3.exe are installed in 'C:\python\python310\Scripts' which is not on PATH. Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location. Successfully installed pip-22.3 (env) C:\django\myproject>
-
Another important step, it is installing the django-extensions as follows :
(env) C:\django\myproject>python -m pip install django-extensions Collecting django-extensions Downloading django_extensions-3.2.1-py3-none-any.whl (229 kB) ---------------------------------------- 229.4/229.4 kB 100.9 kB/s eta 0:00:00 Requirement already satisfied: Django>=3.2 in c:\python\python310\lib\site-packages (from django-extensions) (4.1.1) Requirement already satisfied: sqlparse>=0.2.2 in c:\python\python310\lib\site-packages (from Django>=3.2->django-extensions) (0.4.2) Requirement already satisfied: asgiref<4,>=3.5.2 in c:\python\python310\lib\site-packages (from Django>=3.2->django-extensions) (3.5.2) Requirement already satisfied: tzdata in c:\python\python310\lib\site-packages (from Django>=3.2->django-extensions) (2021.5) Installing collected packages: django-extensions Successfully installed django-extensions-3.2.1 (env) C:\django\myproject>
After that, do not forget to register the ‘django-extensions’ library in the Django project. Do it by adding ‘django-extensions’ for the INSTALLED_APPS property exist as part of the configuration in the ‘settings.py’ file as follows :
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django_extensions', ]
Actually, the django-extensions plugin library is very important for adding functionality to the Django project or improving the Django project performance, even making the Django project more user-friendly.
-
Furthermore, do not forget to add another python library by installing ‘pyparsing’ and ‘pydot’ as follows :
(env) C:\django\myproject>python -m pip install pyparsing pydot Requirement already satisfied: pyparsing in c:\python\python310\lib\site-packages (3.0.9) Collecting pydot Downloading pydot-1.4.2-py2.py3-none-any.whl (21 kB) Installing collected packages: pydot Successfully installed pydot-1.4.2 (env) C:\django\myproject>
In this context, the pyparsing and pydot library are very important in order to use the graphviz library. In term of the pyparsing library, it is important for parsing text strings. On the other hand, in term of pydot library, it is useful to create, manipulate, and visualize graphs in DOT format.
-
After doing that in the above step, add a certain configuration for defining GRAPH_MODELS property in the settings.conf file as follows :
GRAPH_MODELS ={ 'all_applications': True, 'graph_models': True, }
Continue on after, just generate the dot file as follows :
(env) C:\django\myproject>python manage.py graph_models -a > erd.dot (env) C:\django\myproject>
-
Continuing the previous step, generate the image which is mainly displaying the entity relationship diagrams (ERD) as follows :
(env) C:\django\myproject>python manage.py graph_models -a digraph model_graph { // Dotfile by Django-Extensions graph_models // Created: 2022-10-17 13:14 // Cli Options: -a fontname = "Roboto" fontsize = 8 splines = true rankdir = "TB" node [ fontname = "Roboto" fontsize = 8 shape = "plaintext" ] edge [ fontname = "Roboto" fontsize = 8 ] // Labels django_contrib_admin_models_LogEntry [label=< <TABLE BGCOLOR="white" BORDER="1" CELLBORDER="0" CELLSPACING="0"> <TR><TD COLSPAN="2" CELLPADDING="5" ALIGN="CENTER" BGCOLOR="#1b563f"> <FONT FACE="Roboto" COLOR="white" POINT-SIZE="10"><B> LogEntry </B></FONT></TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><B>id</B></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><B>AutoField</B></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT COLOR="#7B7B7B" FACE="Roboto"><B>content_type</B></FONT> </TD><TD ALIGN="LEFT"> <FONT COLOR="#7B7B7B" FACE="Roboto"><B>ForeignKey (id)</B></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><B>user</B></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><B>ForeignKey (id)</B></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto">action_flag</FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto">PositiveSmallIntegerField</FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto">action_time</FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto">DateTimeField</FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT COLOR="#7B7B7B" FACE="Roboto">change_message</FONT> </TD><TD ALIGN="LEFT"> <FONT COLOR="#7B7B7B" FACE="Roboto">TextField</FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT COLOR="#7B7B7B" FACE="Roboto">object_id</FONT> </TD><TD ALIGN="LEFT"> <FONT COLOR="#7B7B7B" FACE="Roboto">TextField</FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto">object_repr</FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto">CharField</FONT> </TD></TR> </TABLE> >] django_contrib_auth_models_AbstractUser [label=< <TABLE BGCOLOR="white" BORDER="1" CELLBORDER="0" CELLSPACING="0"> <TR><TD COLSPAN="2" CELLPADDING="5" ALIGN="CENTER" BGCOLOR="#1b563f"> <FONT FACE="Roboto" COLOR="white" POINT-SIZE="10"><B> AbstractUser<BR/><<FONT FACE="Roboto"><I>AbstractBaseUser,PermissionsMixin</I></FONT>> </B></FONT></TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto">date_joined</FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto">DateTimeField</FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT COLOR="#7B7B7B" FACE="Roboto">email</FONT> </TD><TD ALIGN="LEFT"> <FONT COLOR="#7B7B7B" FACE="Roboto">EmailField</FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT COLOR="#7B7B7B" FACE="Roboto">first_name</FONT> </TD><TD ALIGN="LEFT"> <FONT COLOR="#7B7B7B" FACE="Roboto">CharField</FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto">is_active</FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto">BooleanField</FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto">is_staff</FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto">BooleanField</FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><I>is_superuser</I></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><I>BooleanField</I></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT COLOR="#7B7B7B" FACE="Roboto"><I>last_login</I></FONT> </TD><TD ALIGN="LEFT"> <FONT COLOR="#7B7B7B" FACE="Roboto"><I>DateTimeField</I></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT COLOR="#7B7B7B" FACE="Roboto">last_name</FONT> </TD><TD ALIGN="LEFT"> <FONT COLOR="#7B7B7B" FACE="Roboto">CharField</FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><I>password</I></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><I>CharField</I></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto">username</FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto">CharField</FONT> </TD></TR> </TABLE> >] django_contrib_auth_models_Permission [label=< <TABLE BGCOLOR="white" BORDER="1" CELLBORDER="0" CELLSPACING="0"> <TR><TD COLSPAN="2" CELLPADDING="5" ALIGN="CENTER" BGCOLOR="#1b563f"> <FONT FACE="Roboto" COLOR="white" POINT-SIZE="10"><B> Permission </B></FONT></TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><B>id</B></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><B>AutoField</B></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><B>content_type</B></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><B>ForeignKey (id)</B></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto">codename</FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto">CharField</FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto">name</FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto">CharField</FONT> </TD></TR> </TABLE> >] django_contrib_auth_models_Group [label=< <TABLE BGCOLOR="white" BORDER="1" CELLBORDER="0" CELLSPACING="0"> <TR><TD COLSPAN="2" CELLPADDING="5" ALIGN="CENTER" BGCOLOR="#1b563f"> <FONT FACE="Roboto" COLOR="white" POINT-SIZE="10"><B> Group </B></FONT></TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><B>id</B></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><B>AutoField</B></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto">name</FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto">CharField</FONT> </TD></TR> </TABLE> >] django_contrib_auth_models_User [label=< <TABLE BGCOLOR="white" BORDER="1" CELLBORDER="0" CELLSPACING="0"> <TR><TD COLSPAN="2" CELLPADDING="5" ALIGN="CENTER" BGCOLOR="#1b563f"> <FONT FACE="Roboto" COLOR="white" POINT-SIZE="10"><B> User<BR/><<FONT FACE="Roboto"><I>AbstractUser</I></FONT>> </B></FONT></TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><B>id</B></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><B>AutoField</B></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><I>date_joined</I></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><I>DateTimeField</I></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT COLOR="#7B7B7B" FACE="Roboto"><I>email</I></FONT> </TD><TD ALIGN="LEFT"> <FONT COLOR="#7B7B7B" FACE="Roboto"><I>EmailField</I></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT COLOR="#7B7B7B" FACE="Roboto"><I>first_name</I></FONT> </TD><TD ALIGN="LEFT"> <FONT COLOR="#7B7B7B" FACE="Roboto"><I>CharField</I></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><I>is_active</I></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><I>BooleanField</I></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><I>is_staff</I></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><I>BooleanField</I></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><I>is_superuser</I></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><I>BooleanField</I></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT COLOR="#7B7B7B" FACE="Roboto"><I>last_login</I></FONT> </TD><TD ALIGN="LEFT"> <FONT COLOR="#7B7B7B" FACE="Roboto"><I>DateTimeField</I></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT COLOR="#7B7B7B" FACE="Roboto"><I>last_name</I></FONT> </TD><TD ALIGN="LEFT"> <FONT COLOR="#7B7B7B" FACE="Roboto"><I>CharField</I></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><I>password</I></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><I>CharField</I></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><I>username</I></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><I>CharField</I></FONT> </TD></TR> </TABLE> >] django_contrib_contenttypes_models_ContentType [label=< <TABLE BGCOLOR="white" BORDER="1" CELLBORDER="0" CELLSPACING="0"> <TR><TD COLSPAN="2" CELLPADDING="5" ALIGN="CENTER" BGCOLOR="#1b563f"> <FONT FACE="Roboto" COLOR="white" POINT-SIZE="10"><B> ContentType </B></FONT></TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><B>id</B></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><B>AutoField</B></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto">app_label</FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto">CharField</FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto">model</FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto">CharField</FONT> </TD></TR> </TABLE> >] django_contrib_sessions_base_session_AbstractBaseSession [label=< <TABLE BGCOLOR="white" BORDER="1" CELLBORDER="0" CELLSPACING="0"> <TR><TD COLSPAN="2" CELLPADDING="5" ALIGN="CENTER" BGCOLOR="#1b563f"> <FONT FACE="Roboto" COLOR="white" POINT-SIZE="10"><B> AbstractBaseSession </B></FONT></TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto">expire_date</FONT> </TD><TD ALIN="LEFT"> <FONT FACE="Roboto">DateTimeField</FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto">session_data</FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto">TextField</FONT> </TD></TR> </TABLE> >] django_contrib_sessions_models_Session [label=< <TABLE BGCOLOR="white" BORDER="1" CELLBORDER="0" CELLSPACING="0"> <TR><TD COLSPAN="2" CELLPADDING="5" ALIGN="CENTER" BGCOLOR="#1b563f"> <FONT FACE="Roboto" COLOR="white" POINT-SIZE="10"><B> Session<BR/><<FONT FACE="Roboto"><I>AbstractBaseSession</I></FONT>> </B></FONT></TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><I><B>session_key</B></I></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><I><B>CharField</B></I></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><I>expire_date</I></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><I>DateTimeField</I></FONT> </TD></TR> <TR><TD ALIGN="LEFT" BORDER="0"> <FONT FACE="Roboto"><I>session_data</I></FONT> </TD><TD ALIGN="LEFT"> <FONT FACE="Roboto"><I>TextField</I></FONT> </TD></TR> </TABLE> >] // Relations django_contrib_admin_models_LogEntry -> django_contrib_auth_models_User [label=" user (logentry)"] [arrowhead=none, arrowtail=dot, dir=both]; django_contrib_admin_models_LogEntry -> django_contrib_contenttypes_models_ContentType [label=" content_type (logentry)"] [arrowhead=none, arrowtail=dot, dir=both]; django_contrib_auth_base_user_AbstractBaseUser [label=< <TABLE BGCOLOR="white" BORDER="0" CELLBORDER="0" CELLSPACING="0"> <TR><TD COLSPAN="2" CELLPADDING="4" ALIGN="CENTER" BGCOLOR="#1b563f"> <FONT FACE="Roboto" POINT-SIZE="12" COLOR="white">AbstractBaseUser</FONT> </TD></TR> </TABLE> >] django_contrib_auth_models_AbstractUser -> django_contrib_auth_base_user_AbstractBaseUser [label=" abstract\ninheritance"] [arrowhead=empty, arrowtail=none, dir=both]; django_contrib_auth_models_PermissionsMixin [label=< <TABLE BGCOLOR="white" BORDER="0" CELLBORDER="0" CELLSPACING="0"> <TR><TD COLSPAN="2" CELLPADDING="4" ALIGN="CENTER" BGCOLOR="#1b563f"> <FONT FACE="Roboto" POINT-SIZE="12" COLOR="white">PermissionsMixin</FONT> </TD></TR> </TABLE> >] django_contrib_auth_models_AbstractUser -> django_contrib_auth_models_PermissionsMixin [label=" abstract\ninheritance"] [arrowhead=empty, arrowtail=none, dir=both]; django_contrib_auth_models_Permission -> django_contrib_contenttypes_models_ContentType [label=" content_type (permission)"] [arrowhead=none, arrowtail=dot, dir=both]; django_contrib_auth_models_Group -> django_contrib_auth_models_Permission [label=" permissions (group)"] [arrowhead=dot arrowtail=dot, dir=both]; django_contrib_auth_models_User -> django_contrib_auth_models_Group [label=" groups (user)"] [arrowhead=dot arrowtail=dot, dir=both]; django_contrib_auth_models_User -> django_contrib_auth_models_Permission [label=" user_permissions (user)"] [arrowhead=dot arrowtail=dot, dir=both]; django_contrib_auth_models_User -> django_contrib_auth_models_AbstractUser [label=" abstract\ninheritance"] [arrowhead=empty, arrowtail=none, dir=both]; django_contrib_sessions_models_Session -> django_contrib_sessions_base_session_AbstractBaseSession [label=" abstract\ninheritance"] [arrowhead=empty, arrowtail=none, dir=both]; } (env) C:\django\myproject>
-
After finishing the previous step for generating “erd.dot” file which is only comply as a format file suitable with graphviz tool, generate the image version of it. In other words, it is converting the dot format file into an image format file. Following below execution, it will be available to show visual representation of the entity relationship diagram (ERD) of the models and the relationships of it as follows :
(env) C:\django\myproject>python manage.py graph_models -a > erd.dot && python manage.py graph_models --pydot -a -g -o erd.png (env) C:\django\myproject>
-
Finally, just check the gnerated image which is displaying the entity relationship diagram (ERD) for the database used by the Django application. Below is the display of that image :