Django Web Application CRUD sample with SQL Server

  • This tutorial covers the basics of a Python Django web application using SQL Server database.
    Learn how to set up Django framework for first time in your machine, how to run the Django applications, basic set up for your first HTML page, database CRUD actions like create a record, fetch data, update a record and delete.
    In this sample, pyodbc adapter is used to connect to the SQL Server database.

  • Install Python and setup Virtual Environment

    Download and install the latest version of python from Python Website if not already done.

    Keep your favourite Python editor ready. This can be a basic notepad application available by default for your OS or you can download and install any free editor like VS Code.

    Next step is to set up a virtual environment.
    For that, go to the command prompt and cd to the folder where you are going to keep your project.
    Run command python -m venv CarSalesVENV to create a project folder CarSales and a virtual environment for it.
    Activate the VE using command:

    For Windows:
    CarSalesVENV\Scripts\activate.bat
    For Linux, macOS:
    source CarSalesVENV /bin/activate

    After VE activation, from cmd type cd CarSalesVENV to navigate to the project folder.

  • Install pyodbc

    For SQL Server connection we are going to use the pyodbc library. For quick reference on pyodbc click pyodbc basics.
    Install it using the command: pip install pyodbc

    pyodbc installation may some times throw an error message like Microsoft Visual C++ 14.0 or greater is required.
    Refer next section to fix this error.

  • pyodbc Installation Error - Microsoft Visual C++ 14.0 or greater is required

    This issue is caused by the fact that the latest version of pyodbc is not optimised for the python version that is installed in our machines.
    For example, at the time of writing this article, we had python 3.10.0 as the latest version in our machine and pyodbc version was 4.0.32 and this pyodbc version was throwing this error.
    Follow the below steps to fix the issue.

    Delete the already created virtual environment. Set it up again using the command.

    For Windows:
    py -3.9 -m venv CarSalesVENV
    For Linux, macOS:
    python3.9 -m venv CarSalesVENV

    Install pyodbc using command: pip3.9 install pyodbc

  • To check if pyodbc installed successfully

    Type command pip3.9 freeze
    Should give an output like:

    pyodbc==4.0.32
    
  • Install Django Framework

    To install Django, run command pip install django or pip3.9 install django (if we are using Python 3.9).

    Run pip freeze or pip3.9 freeze to check if Django installed successfully. Should give an output like this.

    asgiref==3.4.1
    Django==3.2.9
    pyodbc==4.0.32
    pytz==2021.3
    sqlparse==0.4.2
    
  • Initial steps for Django Web Apps

    A Django application is structured as a top level Django Project with zero or more Django Apps (modules) within it. Project will contain common codes specific to all sub apps.
    For our example, we will create a project within our virtual environment and an app inside it. We will explain the initial setup in multiple steps.

    Step 1: Create Django Project

    To create a project run:
    django-admin startproject CarSalesProject .

    Running the above command will create a project named CarSalesProject and a python file manage.py will get added. We are providing a ' .' after the project name to avoid an additional folder with the same name being created. See the folder structure after creating project.

    Django SQL Server - Config
    Step 2: Create Django App

    Now on, we don't have to use django-admin in our commands. Use the below command to create our CarSales app.
    python manage.py startapp CarSales

    A new app folder will get created with some files in it. For more details on the files created, you can refer Django Basics.
    New folder structure below:

    Django SQL Server - Config
    Step 3: Include app to our project

    For this, in settings.py, add our new app CarSales (case sensitive) to INSTALLED_APPS list as below.

    Django SQL Server - Settings
  • Loading First HTML Page

    This part explains how we are going to define the routes and where to place our html files. We are going to work on four files highlighted in below image. An html file and 2 urls.py file and views.py file
    Html files should be placed within a folder named templates. Create this folder in our CarSales app.

    Django SQL Server - Config

    Add a new html file carslist.html, inside templates folder.
    We should have 2 urls.py, one inside, project folder and one inside app folder. If not available, create these files. urls.py in project folder adds a reference to the app urls.py.
    In app urls.py we define the urlpatterns for this module.
    In views.py we define the htmls to render for each route. Code provided below.

    Run the app using command python manage.py runserver
    Copy the url from cmd and browse. We should get below output window.

    Django SQL Server - First Page
  • SQL Server Database Setup

    Connect to your SQL server instance and create a database CarSales. Set up login for the database (Not covered here). Create a table TblCars with below structure and insert below set of data.

    CREATE TABLE [dbo].[TblCars](
    	[ID] [int] NOT NULL,
    	[Name] [varchar](100) NULL,
    	[Year] [int] NOT NULL,
    	[Price] [float] NOT NULL)
    
    INSERT INTO TblCars VALUES (1, 'Toyota Camry', 2018, 2000)
    INSERT INTO TblCars VALUES (2, 'Honda Civic', 2019, 2200)
    INSERT INTO TblCars VALUES (3, 'Chevrolet Silverado', 2017, 1800)
    INSERT INTO TblCars VALUES (4, 'Ford F-150', 2020, 2500)
    INSERT INTO TblCars VALUES (5, 'Nissan Altima', 2021, 3000)
    
  • Fetch data from SQL Server DB and list

    carslist.html is going to hold the list of cars available for sale. To list the items, add below code in the body of html. Here, we using a for loop to bind the data to a table.
    Now modify views.py as below to read the data from SQL Server database. Import pyodbc. Bind data to the html using render function.

    For styling we will use Bootstrap 5. Add below 2 lines inside head of html.

    
    <link rel="stylesheet" crossorigin="anonymous"
    href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" >
        
    <script crossorigin="anonymous"
    src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" >
    </script>
    
    

    On refreshing the web page, we will get the below output window.

    Django and SQL Server - List Items
  • Insert new item to SQL Server DB

    Add a new button in the carslist.html above the table.

    <a class="btn btn-primary" href="addcar">Add New Car</a>
    

    Add a new url pattern for addcar in the app urls.py.

    from django.urls import path
    from . import views
    urlpatterns = [
        path('', views.carslist, name = 'carslist'),
        path('addcar', views.addcar, name = 'addcar')
    ]
    

    Add new html file addcar.html in templates folder and place below code.
    Html uses forms. To handle forms in Django we need a form class. Add an new file forms.py in the CarSales app folder and include the form details.
    Then add below code in view.py as the second function below carslist function.

    Also import the form class and redirect in view.py

    from django.shortcuts import render, redirect
    from django.apps import apps
    import pyodbc
    
    from .forms import CarForm
    

    In the view.py, we are defining a new function for addcar. We are using the same method for GET and POST. GET is just rendering addcar.html. In POST, we are reading data from form controls and save data to SQL Server table and then redirect to list page.

    In HTML page, we are defining a form with 4 text boxes. Each has a name provided. This name is used in the view.py while reading data from controls.
    In the HTML form, we have to add {% csrf_token %} next to form tag to avoid csrf verification failed error. On rerun, we can navigate to Create page as below and add new Car.

    Django and SQL Server - Add an Item
  • Update items - SQL Server DB

    For update and delete we will add 2 links in the carslist.html page as below.

    Copied
    <table class="table">
        <thead>
            <tr>
            <th scope="col">Id</th>
            <th scope="col">Name</th>
            <th scope="col">Year</th>
            <th scope="col">Price</th>
            <th scope="col">Edit</th>
            <th scope="col">Delete</th>
            </tr>
        </thead>
        <tbody>
            {% for car in cars %}
                <tr>
                    <td>{{ car.id }}</th>
                    <td>{{ car.name }}</td>
                    <td>{{ car.year }}</td>
                    <td>{{ car.price }}</td>
                    <td><a href='updatecar/{{ car.id }}'>Edit</a></td>
                    <td><a href='deletecar/{{ car.id }}'>Delete</a></td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
    

    For easier understanding, we are going to keep separate routes for create and update, although we are using the same addcar.html for update also. For update we will provide the route name updatecar.
    In addcar.html, in order to populate the values, we have to use the value attribute and bind the car object values as in html provided below.

    In views.py, add new updatecar function. In GET, we are filtering details based on selected id and using fetchall() function, assigning it to a list variable and pass it to the addcar.html page.
    In POST, we are using the update command and commit
    Note: We have to disable Id textbox to not make changes to Id. Here we are not doing it and if Id is changed no update will happen.

    Also, add a new url pattern for updatecar in the app urls.py.

    from django.urls import path
    from . import views
    urlpatterns = [
        path('', views.carslist, name = 'carslist'),
        path('addcar', views.addcar, name = 'addcar'),
        path('updatecar/<int:id>', views.updatecar, name = 'updatecar')
    ]
    

    After the above changes, update will work, but create will throw an error. To fix this, change the render line of addcar as below.

    return render(request, 'addcar.html', {'car':{}})
    

    We are binding an empty car object to make it working.

  • Delete an Item from SQL Server DB

    For delete, we will add a new route deletecar. And just need to provide delete query as below. If needed, a confirm popup also can be added.

    Copied
    def deletecar(request, id):
        conn = connection()
        cursor = conn.cursor()
        cursor.execute("DELETE FROM dbo.TblCars WHERE id = ?", id)
        conn.commit()
        conn.close()
        return redirect('carslist')
    

    Then add new url pattern for deletecar in the app urls.py.

    from django.urls import path
    from . import views
    urlpatterns = [
        path('', views.carslist, name = 'carslist'),
        path('addcar', views.addcar, name = 'addcar'),
        path('updatecar/<int:id>', views.updatecar, name = 'updatecar'),
        path('deletecar/<int:id>', views.deletecar, name = 'deletecar')
    ]
    
  • Django CRUD with SQL Server database - Complete code

    Below listed are the files with code changes. Also a one line change required in Settings.py which is explained at the beginning.

Absolute Code Works - Python Topics