Getting Started with Django, MySQL and React.js: Backend

Getting Started with Django, MySQL and React.

js: BackendChrysostom MurithiBlockedUnblockFollowFollowingMay 13This is a beginner’s guide to Django Framework for backend Development with MySQL, DjangoRestFramework and frontend with React.

js.

We are creating a simple system that displays database data on a React application.

Illustration of the conceptDjango Installation and Python Virtual EnvironmentYou want to create a development environment which you can control.

Virtual Environments help you install all packages that you need for a specific development task without necessarily affecting your base system.

It also helps you manage dependencies when deploying the application.

–Virtual Environment$sudo apt install python3-venv python3-pip$python3 -m venv “/path to your location folder”–activate the virtual environment$ source <location folder>/bin/activate–install latest django version$pip install django$pip install djangorestframework—start django project and app.

$django-admin startproject backend$ cd backend$python manage.

py startapp employee_appDjango project is the main project directory, and applications go inside the project folder.

You can have many applications in one project.

In our case we call the project ‘backend’ and the first app ‘employee_app’Connecting Django to MySQLConventionally, Django manages database using models.

Django models are mappings of the database, which helps you interact with the database even with little knowledge of SQL syntax.

However, if you have a database that has existing data, Django helps you inspect the database and automatically generate the corresponding models for you.

I have used this SQL file to create my Database.

–Create SQL database in the projec's root directory.

I am running my Database as root user, you can use different user.

$mysql -u 'root' < "employees.

sql" -pChange the Django default Database from sqlite3 to MySQLIt is recommended that you avoid typing the password in the settings.

py file.

You can create an environment variable and access it from the settings.

py file$DB_PASS='mypassword'$export DB_PASSEdit the settings.

py fileimport osdef env_var(name):'''gets the environment variables'''try: return str(os.

environ[name])except: raise KeyErrorDATABASES = { 'default': { 'ENGINE': 'django.

db.

backends.

mysql', 'NAME':'employees', 'USER':'root', 'PASSWORD':env_var('DB_PASS'), 'HOST':'0.

0.

0.

0', 'PORT':''}}Creating the Database Models using InspectDBIf you have a database that has existing data, Django helps you inspect the database and automatically generate the corresponding models for you.

$python manage.

py inspectdb > employee_app/models.

pyPart of the generated models.

py filefrom django.

db import modelsclass Employees(models.

Model): emp_no = models.

IntegerField(primary_key=True) birth_date = models.

DateField() first_name = models.

CharField(max_length=20) last_name = models.

CharField(max_length=20) gender = models.

CharField(max_length=1) hire_date = models.

DateField() class Meta: managed = False db_table = 'employees' def __str__(self): return self.

first_nameclass Departments(models.

Model): dept_no = models.

CharField(primary_key=True, max_length=10) dept_name = models.

CharField(unique=True, max_length=40) class Meta: managed = False db_table = 'departments' def __str__(self): return self.

dept_nameclass DeptEmp(models.

Model): emp_no = models.

OneToOneField('Employees', models.

DO_NOTHING, db_column='emp_no', primary_key=True) dept_no = models.

ForeignKey(Departments, models.

DO_NOTHING, db_column='dept_no') from_date = models.

DateField() to_date = models.

DateField() class Meta: managed = False db_table = 'dept_emp' unique_together = (('emp_no', 'dept_no'),)class DeptManager(models.

Model): emp_no = models.

OneToOneField('Employees', models.

DO_NOTHING, db_column='emp_no', primary_key=True) dept_no = models.

ForeignKey(Departments, models.

DO_NOTHING, db_column='dept_no') from_date = models.

DateField() to_date = models.

DateField() class Meta: managed = False db_table = 'dept_manager' unique_together = (('emp_no', 'dept_no'),)class Salaries(models.

Model): emp_no = models.

OneToOneField(Employees, models.

DO_NOTHING, db_column='emp_no', primary_key=True) salary = models.

IntegerField() from_date = models.

DateField() to_date = models.

DateField() class Meta: managed = False db_table = 'salaries' unique_together = (('emp_no', 'from_date'),)class Titles(models.

Model): emp_no = models.

OneToOneField(Employees, models.

DO_NOTHING, db_column='emp_no', primary_key=True) title = models.

CharField(max_length=50) from_date = models.

DateField() to_date = models.

DateField(blank=True, null=True) class Meta: managed = False db_table = 'titles' unique_together = (('emp_no', 'title', 'from_date'),)Make Migrations and Migrate your Models$python manage.

py makemigrations$python mange.

py migrateAdd the employee_app and restframework in settings.

py under installed appsINSTALLED_APPS = [ 'django.

contrib.

admin', 'django.

contrib.

auth', 'django.

contrib.

contenttypes', 'django.

contrib.

sessions', 'django.

contrib.

messages', 'django.

contrib.

staticfiles', 'employees_app', 'rest_framework',]Handling Django Rest APIDjango obtains database data in form of complex data types such as querysets and instances of models.

It is necessary to convert these structures to python objects that can be rendered to the frontend as JSON or XML objects.

Serializers serve this purpose.

SerializersCreate “serializers.

py” in the employee_app.

Create a Serializer for each model in the models.

py file.

djangorestframework has several types of serializers.

In this case with are inheriting the ModelSerializer type and returning all fields of the tables.

from rest_framework import serializersfrom .

models import *class EmployeeSerializer(serializers.

ModelSerializer): class Meta: model = Employees fields = "__all__"class DepartmentsSerializer(serializers.

ModelSerializer): class Meta: model = Departments fields = "__all__"class DeptEmpSerializer(serializers.

ModelSerializer): class Meta: model = DeptEmp fields = "__all__"class DeptManagerSerializer(serializers.

ModelSerializer): class Meta: model = DeptManager fields = "__all__"class SalariesSerializer(serializers.

ModelSerializer): class Meta: model = Salaries fields = "__all__"class TitlesSerializers(serializers.

ModelSerializer): class Meta: model = Titles fields = "__all__"ViewsViews helps the user to interact with the database using viewsets.

The idea is to create a query that fetches data from the database using the models, then pass the data through the Serializer before exposing it to the user.

In each view, we define the serializer we are using, and the create a queryset, that specifies the type and amount of content we want to getModify the views.

py file in the employee_app.

I am limiting my queries to a few rows became the database contains hundreds of thousands entries.

You can create more advanced viewsets.

from django.

shortcuts import renderfrom rest_framework import viewsetsfrom .

serializers import *from .

models import *class EmployeeAPI(viewsets.

ModelViewSet): serializer_class = EmployeeSerializer queryset = Employees.

objects.

all()[:5]class DepartmentsAPI(viewsets.

ModelViewSet): serializer_class = DepartmentsSerializer queryset = Departments.

objects.

all()[:5]class DeptManagerAPI(viewsets.

ModelViewSet): serializer_class = DeptManagerSerializer queryset = DeptManager.

objects.

all()[:5]class DeptEmpAPI(viewsets.

ModelViewSet): serializer_class = DeptEmpSerializer queryset = DeptEmp.

objects.

all()[:5]class SalariesAPI(viewsets.

ModelViewSet): serializer_class = SalariesSerializer queryset = Salaries.

objects.

all()[:5]class TitlesAPI(viewsets.

ModelViewSet): serializer_class = TitlesSerializers queryset = Titles.

objects.

all()[:5]URLsWe will use the rest_framework’s routers to dynamically create urls for our views.

all we need to do is register the viewsEdit the urls.

py files in the project directoryfrom django.

contrib import adminfrom django.

urls import path, includefrom rest_framework import routersfrom employee_app import views#Use the router to dynamically create our urlsrouter = routers.

DefaultRouter()router.

register('employees', views.

EmployeeAPI)router.

register('departments', views.

DepartmentsAPI)router.

register('deptemp', views.

DeptEmpAPI)router.

register('deptmanager', views.

DeptManagerAPI)router.

register('salaries', views.

SalariesAPI)router.

register('titles', views.

TitlesAPI)urlpatterns = [path('admin/', admin.

site.

urls),path('api/', include(router.

urls))]We need to register the models in the admin site.

Open admin.

py in the project directory.

from django.

contrib import adminfrom .

import models# Register your models here.

admin.

site.

register(models.

Employees)admin.

site.

register(models.

Departments)admin.

site.

register(models.

DeptEmp)admin.

site.

register(models.

DeptManager)admin.

site.

register(models.

Salaries)admin.

site.

register(models.

Titles)Testing our AppHaving saved these changes, we run our server and test the apisFrom backend directory, run:$python manage.

py runserver 0.

0.

0.

0:8080Open your browser and enter the url http://127.

0.

0.

1:8080/apiExpected ResultsHTTP 200 OKAllow: GET, HEAD, OPTIONSContent-Type: application/jsonVary: Accept{ "employees": "http://127.

0.

0.

1:8080/api/employees/", "departments": "http://127.

0.

0.

1:8080/api/departments/", "deptemp": "http://127.

0.

0.

1:8080/api/deptemp/", "deptmanager": "http://127.

0.

0.

1:8080/api/deptmanager/", "salaries": "http://127.

0.

0.

1:8080/api/salaries/", "titles": "http://127.

0.

0.

1:8080/api/titles/"}Click on any of the links and you should see some data from our sql database displayed in JSON format.

Salaries Api List (“http://127.

0.

0.

1:8080/api/salaries/")HTTP 200 OKAllow: GET, POST, HEAD, OPTIONSContent-Type: application/jsonVary: Accept[{ "emp_no": 10001, "salary": 60117, "from_date": "1986-06-26", "to_date": "1987-06-26"},{ "emp_no": 10001, "salary": 62102, "from_date": "1987-06-26", "to_date": "1988-06-25"},{ "emp_no": 10001, "salary": 66074, "from_date": "1988-06-25", "to_date": "1989-06-25"},We now have a working backend API using Django and MySQL.

Next we will create a React Application that display this information in a browser.

Cross Origin Resource Sharing (CORS)Accessing Django API from a react frontend or any other framework is by default disabled.

To allow for this sharing install corsheader in django from pip.

$pip install django-cors-headersAdd corsheaders in the installed apps in settings.

py and add a middleware to listen on the responses.

Ensure that corsheaders.

middleware is the first on the list.

Next create a list of allowed hosts to connect to this server by creating a CORS_ORIGIN_WHITELIST.

I have allowed the default React_app url.

If you want to allow all hosts, set CORS_ORIGIN_ALLOW_ALL=TrueINSTALLED_APPS = ( .

'corsheaders', .

)MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.

10 'corsheaders.

middleware.

CorsMiddleware', 'django.

middleware.

common.

CommonMiddleware', .

]CORS_ORIGIN_WHITELIST = [ "http://localhost:3000)Next: We will create a React App to access this API.. More details

Leave a Reply