HI WELCOME TO SIRING

Python Django + Microsoft SQL Server CRUD API tutorial

Leave a Comment

 In this post we will see how to create CRUD APIs using Python Django as backend and Microsoft SQL Server for database.

Lets install the necessary modules needed for our Django project.

First lets install the Django module.

>> pip install django

To create rest APIs we need to install Django rest framework.

>> pip install djangorestframework

By default, the Django project comes with a security that blocks requests coming from different domains. To disable this, lets install Django CORS headers module.

>> pip install django-cors-headers

Now lets create the Django project.

Open the command prompt in the desired folder and type the command.

>> django-admin start project <name of the project>

Lets take a look at some of the important files in the project.

 


>> __init__.py file is just and empty file that indicates that the given folder is a python project or a python module.

>>  asgi.py is the entry point for the asgi compatible webservers.

>> wsgi.py is the entry point for the wsgi compatible web servers.

>> urls.py file contains all the url declarations needed for this project.

>> settings.py file contains all the settings or the configurations needed for the project.

>> manage.py is a command line utility that helps interact with the Django project.

 

Lets simply run the project and see how it looks in the browser using below command.

>> python manage.py runserver

The app is now running in the port 8000.



Lets copy  the url and open in the browser.

What you see on the screen is the default template that comes with every Django project.

 


 

Now lets create an app in our Django project.

Quick difference between projects and apps.

The folder structure that you currently see on the screen is called the project.



A project may have multiple apps.

For example, you can have one app which acts like a blog, or may be another app which acts like a survey form.

Currently this project does not have any app.

Lets create one app to implement our api methods.

To create an app, we need to type this command.

>> python manage.py startapp <the name of the app>


Next let us register the app and the required modules in settings.py file.

In the installed apps section, lets add Rest framework, cors header, and the newly created app.

We need to add the cors headers in middle ware section as well.

We will also add instruction to enable all domains to access the APIs.

This is not recommended in production. Instead, just add only those domains that needs to be whitelisted.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'corsheaders',
    'EmployeeApp.apps.EmployeeappConfig'
]

CORS_ORIGIN_ALLOW_ALL = True

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

 

Lets create the models needed for our app.

We need two models.

One to store department details and another one to store employee details.

The departments model will have two fields. One to store an autoincremented Department ID, and another one to store Department Name.

Employee model will have five fields.

Employee ID, Employee name, Department, Date of joining, and photo file name which stores the uploaded profile picture file name.

Models.py complete code:

from django.db import models

# Create your models here.

class Departments(models.Model):
    DepartmentId = models.AutoField(primary_key=True)
    DepartmentName = models.CharField(max_length=500)

class Employees(models.Model):
    EmployeeId = models.AutoField(primary_key=True)
    EmployeeName = models.CharField(max_length=500)
    Department = models.CharField(max_length=500)
    DateOfJoining = models.DateField()
    PhotoFileName = models.CharField(max_length=500)

We will be using the Microsoft SQL Server database.

To connect to SQL Server from our Python Django app, we need to install the database adapters.

>> pip install pyodbc

>> pip install django-pyodbc-azure

Add the database details in settings.py file.






Lets write the command to make migrations file for our models.

>> python manage.py makemigrations <app name>

After executing this, we can see a migration file which tells us what changes to the database will be done.



Once it looks fine, we can execute the command to push these changes to the database.

>> python manage.py migrate <app name>


Lets create serializers for our models.

Serializers basically help to convert the complex types or model instances into native python data types that can then be easily rendered into json or xml or other content types.

They also help in deserialization which is nothing but converting the passed data back to complex types.

 serializers.py complete code:

from rest_framework import serializers
from EmployeeApp.models import Departments,Employees

class DepartmentSerializer(serializers.ModelSerializer):
    class Meta:
        model=Departments 
        fields=('DepartmentId','DepartmentName')

class EmployeeSerializer(serializers.ModelSerializer):
    class Meta:
        model=Employees 
        fields=('EmployeeId','EmployeeName','Department','DateOfJoining','PhotoFileName')

Lets now start writing the API methods.

views.py code.


from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from rest_framework.parsers import JSONParser
from django.http.response import JsonResponse

from EmployeeApp.models import Departments,Employees
from EmployeeApp.serializers import DepartmentSerializer,EmployeeSerializer

from django.core.files.storage import default_storage

# Create your views here.

@csrf_exempt
def departmentApi(request,id=0):
    if request.method=='GET':
        departments = Departments.objects.all()
        departments_serializer=DepartmentSerializer(departments,many=True)
        return JsonResponse(departments_serializer.data,safe=False)
    elif request.method=='POST':
        department_data=JSONParser().parse(request)
        departments_serializer=DepartmentSerializer(data=department_data)
        if departments_serializer.is_valid():
            departments_serializer.save()
            return JsonResponse("Added Successfully",safe=False)
        return JsonResponse("Failed to Add",safe=False)
    elif request.method=='PUT':
        department_data=JSONParser().parse(request)
        department=Departments.objects.get(DepartmentId=department_data['DepartmentId'])
        departments_serializer=DepartmentSerializer(department,data=department_data)
        if departments_serializer.is_valid():
            departments_serializer.save()
            return JsonResponse("Updated Successfully",safe=False)
        return JsonResponse("Failed to Update")
    elif request.method=='DELETE':
        department=Departments.objects.get(DepartmentId=id)
        department.delete()
        return JsonResponse("Deleted Successfully",safe=False)

@csrf_exempt
def employeeApi(request,id=0):
    if request.method=='GET':
        employees = Employees.objects.all()
        employees_serializer=EmployeeSerializer(employees,many=True)
        return JsonResponse(employees_serializer.data,safe=False)
    elif request.method=='POST':
        employee_data=JSONParser().parse(request)
        employees_serializer=EmployeeSerializer(data=employee_data)
        if employees_serializer.is_valid():
            employees_serializer.save()
            return JsonResponse("Added Successfully",safe=False)
        return JsonResponse("Failed to Add",safe=False)
    elif request.method=='PUT':
        employee_data=JSONParser().parse(request)
        employee=Employees.objects.get(EmployeeId=employee_data['EmployeeId'])
        employees_serializer=EmployeeSerializer(employee,data=employee_data)
        if employees_serializer.is_valid():
            employees_serializer.save()
            return JsonResponse("Updated Successfully",safe=False)
        return JsonResponse("Failed to Update")
    elif request.method=='DELETE':
        employee=Employees.objects.get(EmployeeId=id)
        employee.delete()
        return JsonResponse("Deleted Successfully",safe=False)

@csrf_exempt
def SaveFile(request):
    file=request.FILES['file']
    file_name=default_storage.save(file.name,file)
    return JsonResponse(file_name,safe=False)

For Save File API, create a folder with name 'Photos':

settings.py complete code:


"""
Django settings for DjangoAPI project.

Generated by 'django-admin startproject' using Django 3.2.4.

For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""

from pathlib import Path
import os

BASE_DIR=Path(__file__).resolve(strict=True).parent.parent
MEDIA_URL='/Photos/'
MEDIA_ROOT=os.path.join(BASE_DIR,"Photos")


# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-@oxx-o(4f=mxha%-tlv97)x9m7x_fw=(@*k=*29q%r7c8*)%-&'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'corsheaders',
    'EmployeeApp.apps.EmployeeappConfig'
]

CORS_ORIGIN_ALLOW_ALL = True

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'DjangoAPI.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'DjangoAPI.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'sql_server.pyodbc',
        'NAME': '<db name>',
        'USER':'<user>',
        'PASSWORD':'<password>',
        'HOST':'<server name>',
        'OPTIONS':{
            'driver':'ODBC Driver 17 for SQL Server',
            'isolation_level':'READ UNCOMMITTED' #to prevent deadlocks
        }
    }
}

# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = '/static/'

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

EmployeeApp's urls.py:

from django.conf.urls import url
from EmployeeApp import views

from django.conf.urls.static import static
from django.conf import settings

urlpatterns=[
    url(r'^department$',views.departmentApi),
    url(r'^department/([0-9]+)$',views.departmentApi),

    url(r'^employee$',views.employeeApi),
    url(r'^employee/([0-9]+)$',views.employeeApi),

    url(r'^employee/savefile',views.SaveFile)
]+static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)

Main urls.py:

"""DjangoAPI URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path

from django.conf.urls import url,include

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^',include('EmployeeApp.urls'))
]


Ionic 6 Cordova Geolocation and Geocoder Tutorial

Leave a Comment

 Ionic 6 Angular Geolocation and Geocoder tutorial; This is a step by step tutorial on how to use Cordova Geolocation and Geocoder plugin in an Ionic app to get the current user device position, get current user address.

In this tutorial we are going to learn how to get users device location with latitude and longitude.We will learn to get the users address using Geolocation and Geocoder Plugins.

We will look at how to add target platforms such as iOS, Android or Windows and create the build in Ionic for various devices.

Ionic 6 Angular Get Geolocation Example

  • Step 1: Prerequisite
  • Step 2: Create New Ionic Angular Project
  • Step 3: Install & Configure Cordova Geolocation and Geocoder Plugins
  • Step 4: Get Current Location Latitude and Longitude
  • Step 5: Get Current Address
  • Step 6: Start Ionic App

Prerequisite

We must have the latest version of Node js installed on our device. If you are not having then follow this tutorial on: How to Download and Install Node.js and npm

Create New Ionic / Angular Project

Use the command to install Cordova globally on your machine.

sudo npm install -g cordova ionic
Bash

By using the following command, you can check the Ionic CLI version running on your machine.

ionic -v
Bash

Use below command to update Ionic and Cordova.

sudo npm update -g cordova ionic
Bash

Let’s start installing a brand new Ionic Angular app with the help of Ionic CLI, run the following command in your terminal.

ionic start ionic-geolocation-app blank --type=angular
Bash

Get inside the project folder.

cd ionic-geolocation-app
Bash

Start the app in the browser.

ionic serve --lab
Bash

How to Install & Configure Cordova Geolocation, Geocoder and Ionic Native Plugins

In this step, we will first install then configure Cordova Geolocation, Geocoder and Ionic native plugins in an Ionic app.

Geolocation

The cordova-plugin-geolocation plugin API is based on the W3C Geolocation API Specification and helps to get the location (latitude and longitude) data.

This plugin provides information about the device’s location, such as latitude and longitude. Common sources of location information include Global Positioning System (GPS) and location inferred from network signals such as IP address, RFID, WiFi and Bluetooth MAC addresses, and GSM/CDMA cell IDs.

ionic cordova plugin add cordova-plugin-geolocation
Bash

Install @ionic-native/geolocation via npm using the below command.

npm install @ionic-native/geolocation
React JSX

This geo location plugin provides device data such as device location, latitude and longitude. Common sources of location information include Global Positioning System (GPS) and location inferred from network signals such as IP address, RFID, WiFi and Bluetooth MAC addresses, and GSM/CDMA cell IDs.

It supports following platforms:

  • iOS
  • Android
  • Windows
  • Browser
  • Amazon Fire OS

Add given below configuration to your configuration.xml file for iOS support.

<edit-config file="*-Info.plist" mode="merge" target="NSLocationWhenInUseUsageDescription">
   <string>We use your location for full functionality of certain app features.</string>
</edit-config>
React JSX

Native Geocoder

The native geocoder plugin helps us to get the address for given coordinates and also does forward and reverse geocoding for iOS and Android platforms.

ionic cordova plugin add cordova-plugin-nativegeocoder
npm install @ionic-native/native-geocoder
Bash

Import Plugins in Main AppModule

Add the above plugins in the main Ionic app module file, open app.module.ts file, and import and add plugins in an import array.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
// geolocation and native-geocoder
import { Geolocation } from '@ionic-native/geolocation/ngx';
import { NativeGeocoder } from '@ionic-native/native-geocoder/ngx';
@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
  providers: [
    Geolocation,
    NativeGeocoder,
    { 
      provide: RouteReuseStrategy, 
      useClass: IonicRouteStrategy
    }
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}
TypeScript

Get Current User’s Device Location Latitude and Longitude using Geolocation and Native Geocoder Plugin

Apps like Whatsapp, Uber, Ola, and many more depending on the user’s location, and without location, we can’t imagine modern days web and mobile applications. Almost every application uses the location service to offer excellent services to its users.

Finding a geo location with Cordova Geolocation is very easy, and We are going to get the current lat long of the user’s device.

In this step, I am going to describe how to locate the user’s device position, open home.pge.ts file and add the given code in it.

// home.page.ts
import { Component, NgZone } from '@angular/core';
import { Geolocation } from '@ionic-native/geolocation/ngx';
@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  latitude: any = 0; //latitude
  longitude: any = 0; //longitude
  constructor(
    private geolocation: Geolocation
  ) {}
  options = {
    timeout: 10000, 
    enableHighAccuracy: true, 
    maximumAge: 3600
  };
  // use geolocation to get user's device coordinates
  getCurrentCoordinates() {
    this.geolocation.getCurrentPosition().then((resp) => {
      this.latitude = resp.coords.latitude;
      this.longitude = resp.coords.longitude;
     }).catch((error) => {
       console.log('Error getting location', error);
     });
  }
}
TypeScript

To get the geographical position of a user, we imported the Geolocation API at the top, then injected in the constructor and accessed the getCurrentPosition() method to get the user’s position.

The getCurrentPosition() method returns geolocation data which contains a timestamp, GeoLocation coordinates such as latitude, longitude, altitude, accuracy, alititudeAccuracy, heading and speed.

The getCurrentPosition() function takes 3 parameters, success, error and options. In the options we specify timeout, enableHighAccuracy and maximumAge.

Add the following code in home.page.html file.

// home.page.html
<ion-header>
  <ion-toolbar>
    <ion-title>
        Ionic Geolocation & Geocoder Examples
    </ion-title>
  </ion-toolbar>
</ion-header>
<ion-content>
  <div class="ion-padding">
    <ion-button (click)="getCurrentCoordinates()" expand="block">
      Get Location
    </ion-button>
  <ion-list>
    <ion-list-header>
      <ion-label>Location Coordinates</ion-label>
    </ion-list-header>
    <ion-item>
      <ion-label>
        Latitue
      </ion-label>
      <ion-badge color="danger" slot="end">{{latitude}}</ion-badge>
    </ion-item>
    <ion-item>
      <ion-label>
        Longitude
      </ion-label>
      <ion-badge color="danger" slot="end">{{longitude}}</ion-badge>
    </ion-item>
    </ion-list>    
  </div>
</ion-content>
Markup

Get Current User's Device Location Latitude and Longitude using Geolocation and Native Geocoder Plugin

Getting Current Address

To get the current address of the location. We need to import the following services at the header part of the Ionic TypeScript template.

import { NativeGeocoder, NativeGeocoderResult, NativeGeocoderOptions } from '@ionic-native/native-geocoder/ngx';
TypeScript

Open the home.page.ts file then add the following code.

import { Component, NgZone } from '@angular/core';
import { Geolocation } from '@ionic-native/geolocation/ngx';
import { NativeGeocoder, NativeGeocoderResult, NativeGeocoderOptions } from '@ionic-native/native-geocoder/ngx';
@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  latitude: any = 0; //latitude
  longitude: any = 0; //longitude
  address: string;
  constructor(
    private geolocation: Geolocation,
    private nativeGeocoder: NativeGeocoder
  ) {}
  // geolocation options
  options = {
    timeout: 10000, 
    enableHighAccuracy: true, 
    maximumAge: 3600
  };
  // use geolocation to get user's device coordinates
  getCurrentCoordinates() {
    this.geolocation.getCurrentPosition().then((resp) => {
      console.log(resp)
      this.latitude = resp.coords.latitude;
      this.longitude = resp.coords.longitude;
      this.getAddress(this.latitude, this.longitude);
     }).catch((error) => {
       console.log('Error getting location', error);
     });
  }
  // geocoder options
  nativeGeocoderOptions: NativeGeocoderOptions = {
    useLocale: true,
    maxResults: 5
  };
  // get address using coordinates
  getAddress(lat,long){
    this.nativeGeocoder.reverseGeocode(lat, long, this.nativeGeocoderOptions)
    .then((res: NativeGeocoderResult[]) => {
      this.address = this.pretifyAddress(res[0]);
    })
    .catch((error: any) => {
      alert('Error getting location'+ JSON.stringify(error));
    });
  }
  // address
  pretifyAddress(address){
    let obj = [];
    let data = "";
    for (let key in address) {
      obj.push(address[key]);
    }
    obj.reverse();
    for (let val in obj) {
      if(obj[val].length)
      data += obj[val]+', ';
    }
    return address.slice(0, -2);
  }
}
TypeScript

We defined address variable, then injected the NativeGeocoder API in the constructor.

The getAddress() method takes lat and long parameter, inside the function the reverseGeocode API provides reverseGeocode method that takes lat, long and nativeGeocoderOptions parameters and returns the address array. That raw address data is being filtered by pretifyAddress() method and returning comma separated address.

Start Ionic App in Device

We will learn how to add target platforms for iOS, Android and Windows to test our app.

# iOS
ionic cordova platform add ios
# Android
ionic cordova platform add android
# Windows
ionic cordova platform add windows
Bash

Use the following commands to build your Ionic app for various platforms:

# iOS
ionic cordova build ios
# Android
ionic cordova build android
# Windows
ionic cordova build windows
Bash

Start the app in the device.

# iOS
ionic cordova run ios -l
# Android
ionic cordova run android -l
# Windows
ionic cordova run windows -l
Bash

Conclusion

Finally, Ionic Cordova Geolocation and Geocoder plugins tutorial has been over. In this tutorial we have learned how to:

  • Set up a basic Ionic app from scratch.
  • Install and configure Cordova Geolocation and Geocoder Plugins in Ionic app.
  • Locate Current Location Latitude and Longitude.
  • Get Current User Address.
  • Add Target Platforms.
  • Build Ionic App.