Django – Linux Hint https://linuxhint.com Exploring and Master Linux Ecosystem Wed, 10 Mar 2021 03:25:19 +0000 en-US hourly 1 https://wordpress.org/?v=5.6.2 How to Create Django Views? https://linuxhint.com/create-django-views/ Tue, 09 Mar 2021 05:32:51 +0000 https://linuxhint.com/?p=93540 Different types of data of Django application, such as HTML content, XML data, JSON data, image, 404 error, etc. are transferred to the template through Django view. Each view is created for a specific purpose and associated with a particular template. The data of the view can be generated from the user through HTML form or from the database or business logic. Django views can be created using a method of python class or python function. The class-based views contain many functionalities compared to function-based views. For this, most of the Django applications use class-based views to represent the data of the Django application. The ways of creating the function-based view and class-based view have been explained in this tutorial.

Prerequisites:

Before practicing the examples of this tutorial, you have to complete the following tasks:

  1. Install the Django version 3+ on Ubuntu 20+ (preferably)
  2. Create a Django project
  3. Run the Django server to check whether the server is working properly or not

Setup a Django App:

A. To create a Django app named viewapp, run the following command:

$ python3 manage.py startapp viewapp

B. To create the user for accessing the Django database, run the following command. If you have created the user before then skip this part:

$ python3 manage.py createsuperuser

C. Add the app name in the INSTALLED_APP part of the settings.py file.

INSTALLED_APPS = [
    …..
    'viewapp'
]

D. Create a folder named templates inside the viewapp folder and set the template’s location of the app in the TEMPLATES part of the settings.py file.

TEMPLATES = [
    {
      ….
            'DIRS': ['/home/fahmida/django_pro/viewapp/templates'],
             ….
      },
]

Create a Simple function-based View:

Open the views.py file from the viewapp folder and replace the content of this file with the following script. index() function is used in the script to create the HTML content that will be sent to the browser using the HttpResponse() method. Here, the current date and time of the system will be read using the today() function and the current date value will be generated before sending to the browser.

Views.py

# Import the date module to read the current date
from datetime import date
# Import the HttpResponse module to send data from view to template
from django.http import HttpResponse

# Define function to create function-based view
def index(request):
    # Read the current date
    today = date.today()
    # Set static data for the view
    content = "<center><h1 style='color:green'>Welcome to LinuxHint</h1><h2>"
    content += "Today is " + today.strftime("%B") + " " + today.strftime("%d") + ", " + str(today.year) + "</h2></center>"
    # Sent the content to the browser
    return HttpResponse(content)

Modify the content of the urls.py file with the following script. In the script, the ‘welcome/’ path is defined to call the index() function that will send the HTML content to the template file.

urls.py

# Import path module
from django.urls import path
# Import view module
from viewapp import views

# Call index method to display the content
urlpatterns = [
   # Define path to call index() function
    path('welcome/', views.index)
]

Run the following URL from the browser that will show the following output. A formatted headline text and the current date value are shown in the output.

http://localhost:8000/welcome/

Create a Simple class-based View:

Create a views2.py file inside the viewapp folder and add the following script. MyView class is defined in the script that contains a method named get(). A list variable named listdata is declared in the script to create a list of 10 random numbers. The values of the list will be passed to the template through the HttpResponse() method when this view is called. the random module has been used in the script to generate a random integer number in each iteration of the for loop using the randint() function.

views2.py

# Import the HttpResponse module to send data from view to template
from django.http import HttpResponse
# Import view module
from django.views import View
# Import random module
import random

# Define class for class-based views
class MyView(View):

    def get(self, request):
        # Declare the list variable
        listdata = []
        # Add the first element of the list
        listdata.append('<center><h2>he list of 10 random numbers are:</h2>')
        # Iterate the loop for 10 times
        for n in range(10):
            # Generate a random number within 1 to 50
            random_number = random.randint(1, 50)
            # Add the random number in the list
            listdata.append(random_number)
            # Add a break element in the list
            listdata.append('<br/>')
        # Add the last element of the list
        listdata.append('</center>')
        # Send the list values to the browser
        return HttpResponse(listdata)

Modify the content of the urls.py file with the following script. In the script, the “number/” path is defined to call the MyView.as_view() method that will send the data of the list to the template file.

urls.py

# Import path module
from django.urls import path
# Import view module
from viewapp import views
# Import MyView class
from viewapp.views2 import MyView

# Call the get method of MyView class
urlpatterns = [
   # Define  path to call index() function
   path('welcome/', views.index),
   # Define path to call MyView.as_view() method
    path('number/', MyView.as_view()),
]

Run the following URL from the browser that will show the following output. The numbers of the output will be changed if the page is refreshed because each number of the list will be generated randomly.

http://localhost:8000/number/

Conclusion:

The output of the web application depends on the script of the view file that is a major part of any web application. Function-based views are mostly used in the early version of the Django app and now class-based vies are used in most applications of Django. The ways of creating both types of views have been shown in this tutorial to help the new Django users create their views based on their application.

]]>
How to Use the Model in Django? https://linuxhint.com/use-model-django/ Thu, 04 Mar 2021 12:39:23 +0000 https://linuxhint.com/?p=92828 Model is used in Django application to create a web application with a database. It is a built-in feature of Django to create relational database tables by defining the table structure for the Django project. Each attribute of the model indicates the type of the particular field of the table. A model class will require to define each table of the database. Generally, the name of the model class is defined in the singular form, and Django will create a table name in plural form based on the model class name. Any modifications of the table designed by the model, such as create or update or delete, can be done very easily using the Django admin panel. The same tasks can also be done from the python command line. Creating Django models that will create two relational tables and how they can be accessed using the Django Administration dashboard is shown in this tutorial.

Prerequisites

Before practicing the examples of this tutorial, you have to complete the following tasks.

  1. Install the Django version 3+ on Ubuntu 20+ (preferably)
  2. Create a Django project
  3. Run the Django server to check the server is working properly or not.

Setup a Django app:

Run the following command to create a Django app named model app.

$ python3 manage.py startapp modelapp

Run the following command to create the user for accessing the Django database. If you have created the user before, then you don’t need to run the command.

$ python3 manage.py createsuperuser

Add the app name in the INSTALLED_APP part of the py file.

INSTALLED_APPS = [
    …..
    'model app
]

Create a folder named templates inside the model app folder and set the template’s location of the app in the TEMPLATES part of the py file.

TEMPLATES = [
    {
….
            'DIRS': ['/home/fahmida/django_pro/modelapp/templates'],
             ….
      },
]

Create a model for the database table:

Open the models.py file from the model app folder and add the following script to define the structure of two relational tables. Teacher class is defined to create a table named teachers with name, department, email, and phone fields. Course class is defined to create a table named courses with code, name, credit, and teacher fields. Here, the teacher field of Courses table is the foreign key that will appear from the Teachers table.

models.py

# Import models module
from django.db import models

# Create class to define the structure of Teachers table
class Teacher(models.Model):
    name = models.CharField(max_length=50)
    department = models.CharField(max_length=20)
    email = models.EmailField(max_length=100)
    phone = models.CharField(max_length=50)

# Create class to define the structure of Courses table
class Course(models.Model):
    code = models.CharField(max_length=10)
    name = models.CharField(max_length=50)
    credit = models.FloatField()
    teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)

Run the makemigrations command to create a new migration based on the changes made by the models.

$ python3 manage.py makemigrations model app

Run the migrate command to execute the SQL commands and create all tables in the database defined in the models.py file.

$ python3 manage.py migrate

Modify the content of the admin.py file with the following content. Here, Teacher and Course classes of the models are registered by using the register() method to display the Teachers and Courses tables in the Django administration dashboard.

admin.py

# Import admin module
from django.contrib import admin

# Import the models
from .models import Teacher
from .models import Course

# Register the models
admin.site.register(Teacher)
admin.site.register(Course)

Set URL for admin login:

The path for admin login is defined in the urls.py file for any Django app by default. If the path is not defined in the file, modify the urls.py file with the following script to open the built-in Django Administration Dashboard for the path’ admin/‘.

urls.py

# Import admin module
from django.contrib import admin
# Import path module
from django.urls import path

# Define the path for admin
urlpatterns = [
    path('admin/', admin.site.urls),
]

Insert records in the tables:

Run the following URL from the browser to open the Django Administration Dashboard.

http://localhost:8000/admin

The following tables will be shown for the model app. Any record of the tables can be read, inserted, updated, and deleted from this page.

Click on the Teachers table to insert some records into the table. A form with the necessary fields like the following image will appear for inserting record. There are three buttons in the form to insert records in the table. ‘Save and add another‘ button is used to insert the record and open the form again for inserting the next record. The ‘Save and continue editing‘ button is used to insert the record and open the form again with the data for editing. The ‘Save‘ button is used to insert the record only. Every entry form will contain these three buttons.

After inserting the two teacher’s records, the following information will appear in the browser.

The following form will appear after clicking on the courses table. The Teacher field of the Courses table is related to the Teachers table by the foreign key. The dropdown list with inserted Teacher objects will appear to add the data in this field from the list.

After inserting three records into the Courses table, the following information will appear in the browser. If you want to modify any records of the Courses or the Teachers table, then click on that particular object to open the edit form with the existing data.

You can display the records of both tables in the browser by using the views.py file and creating the temples in the defined template location.  You can check the Django View and Django Template tutorials for these.

Conclusion

The table data can be accessed or modified by Django Administration Dashboard, as explained in this tutorial. But the data can be inserted into the tables by writing a script in the views.py file with or without using the template file.

]]>
How to use Django Serializers https://linuxhint.com/use-django-serializers/ Wed, 24 Feb 2021 17:17:16 +0000 https://linuxhint.com/?p=91436 Serializer is used in Django to convert the model instances or querysets into python supported data types that can be easily rendered into JSON, XML, or other formats. The deserialization can also be done by serializers to get back the original data from the serialized data. This feature is available in Django REST Framework. So, the users have to install this framework to use the serializers. Any webpage of the website may contain HTML, CSS, and data from the database tables. But the API does not understand these types of content, and it can understand the raw data only, that is, JSON data. How the serializers can be used to convert the model instance into JSON format has shown in this tutorial.

Prerequisites:

Before practicing the script of this tutorial, you have to complete the following tasks.

  1. Install the Django version 3+ on Ubuntu 20+ (preferably)
  2. Create a Django project
  3. Run the Django server to check the server is working properly or not.

Setup a Django app for Serializers:

Run the following command to create a Django app named serialapp.

$ python3 manage.py startapp serialapp

Run the following command to create the user for accessing the Django database. If you have created the user before, then you don’t need to run the command.

$ python3 manage.py createsuperuser

Run the following command to install Django REST Framework.

$ pip3 install djangorestframework

Add the rest_framework and app name in the INSTALLED_APP part of the settings.py file.

INSTALLED_APPS = [
         ….
     'rest_framework',
     'serialapp'
]

Create a model for the database table:

Open the models.py file from the serialapp folder and add the following script to define the structure of customers tables. Customer class is defined to create a table named customers with name, address, email, contact_no, and created fields. Here, name, email, and contact_no fields will store character data, the address field will store the text data, and created field will store the DateTime data.

models.py

# Import the models module
from django.db import models

# Define the model class for the customers table
class Customer(models.Model):

    name = models.CharField(max_length=100)
    address = models.TextField()
    email = models.CharField(max_length=50)
    contact_no = models.CharField(max_length=20)
    created = models.DateTimeField(auto_now_add=True)

Run the makemigrations command to create a new migration based on the changes made by the models.

$ python3 manage.py makemigrations serialapp

Run the migrate command to execute the SQL commands and create all tables in the database defined in the models.py file.

$ python3 manage.py migrate

Modify the content of the admin.py file with the following content. Here, the Customer class of the models is registered by using the register() method to display the customers tables in the Django administration dashboard.

admin.py

# Import admin module
from django.contrib import admin
# Import the Customer model
from .models import Customer
# Register the customer model
admin.site.register(Customer)

urls.py

from django.urls import path
from django.contrib import admin

urlpatterns = [
    # Define the path for admin
    path('admin/', admin.site.urls),
]

Add records into the table:

Open the Django Administration page and add some records into the customers table displayed to the browser in JSON format. Here, three records have been inserted.

Modify the views.py:

Open the views.py file from the serialapp and replace the content with the following script. CustomerList class is defined to serialize all the customers’ records and return the data to the browser in JSON format. CustomerDetail class is defined to serialize the particular customer record based on the ID value and return the browser’s data in JSON format. CustomerSerializer is a serializers file that has been created in the next part of this tutorial.

views.py

# Import generics from the Django REST Framework
from rest_framework import generics

# Import Customer model
from .models import Customer

# Import CustomerSerializer from serializers
from .serializers import CustomerSerializer

# Define class to convert all records of the customers table into JSON
class CustomerList(generics.ListCreateAPIView):
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer

# Define class to convert the particular record of the customers table into JSON
class CustomerDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer

Create Serializer:

Create serializers.py file in the same location of the views.py file with the following script. ModelSerializer class is used here to create CustomerSerializer class that returns the serializers class with the fields of the Customer model. The Customer model fields that will be converted into JSON format are mentioned in the Meta class.

serializers.py

# Import serializers module from Django REST Framework
from rest_framework import serializers
# Import Customer model
from .models import Customer

# Define the custom serializers class to convert the Customer model fields into JSON
class CustomerSerializer(serializers.ModelSerializer):

    class Meta:
        model = Customer
        fields = ('id', 'name', 'address', 'email', 'contact_no')

Modify the urls.py file:

Modify the content of the urls.py file with the following script. In the script, the ‘customers/‘ path is defined to display all records of the customers table in JSON format, and the ‘customers/<int:pk>/‘ path is defined to display the particular data of the customers table in JSON format based on ID value.

urls.py

# Import admin module
from django.contrib import admin
# Import path and include module
from django.urls import path
# Import the views
from serialapp import views
# Import format_suffix_patterns from Django REST Framework
from rest_framework.urlpatterns import format_suffix_patterns

urlpatterns = [
    # Define the path for admin
    path('admin/', admin.site.urls),
    # Define the path to get all customers data in JSON format
    path('customers/', views.CustomerList.as_view()),
    # Define the path to get the particular customer data based on ID in JSON format
    path('customers//', views.CustomerDetail.as_view()),


]
urlpatterns = format_suffix_patterns(urlpatterns)

All records of the customers table will be shown in JSON format if the following URL will execute.

 

http://localhost:8000/customers

The record of the second customer will be shown in JSON format if the following URL executes.

http://localhost:8000/customers/2

Conclusion:

The use of serializers in the Django application to convert the model instance into JSON format has shown in this tutorial by using a simple script. The Django users will understand the purpose of using serializers and apply them in their application if required after reading this tutorial.

]]>
How to use queryset in django https://linuxhint.com/use-queryset-django/ Wed, 24 Feb 2021 16:53:23 +0000 https://linuxhint.com/?p=91391 Most of the web applications are implemented with the database now. queryset is used in the Django application to retrieve records by filtering or slicing or ordering the database table without changing the original data. The model used Django to create the table in the database. So, the knowledge of using the model in Django is necessary to understand the use of queryset. The main function of the queryset is to iterate the records of database tables by converting them into SQL queries. It can be used from the python command line or by writing the python script to display the browser’s output. The uses of queryset for retrieving data from a database table in different ways have been explained in this tutorial.

Prerequisites:

Before practicing the script of this tutorial, you have to complete the following tasks.

  1. Install the Django version 3+ on Ubuntu 20+ (preferably)
  2. Create a Django project
  3. Run the Django server to check the server is working properly or not.

Setup a Django app:

Run the following command to create a Django app named queryapp.

$ python3 manage.py startapp queryapp

Run the following command to create the user for accessing the Django database. If you have created the user before, then you don’t need to run the command.

$ python3 manage.py createsuperuser

Add the app name in the INSTALLED_APP part of the settings.py file.

INSTALLED_APPS = [
    …..
    'queryapp'
]

Create a folder named templates inside the queryapp folder and set the template’s location of the app in the TEMPLATES part of the settings.py file.

TEMPLATES = [
    {
….
            'DIRS': ['/home/fahmida/django_pro/queryapp/templates'],
             ….
      },
]

Create a model for the database table:

Open the models.py file from the queryapp folder and add the following script to define the structure of products tables. Product class is defined to create a table named products with name, type, brand, and price fields. Here, name, type, and brand fields will store character data, and the price field will store the integer data.

models.py

# Import models module
from django.db import models

# Define class to create products table
class Product(models.Model):
    name = models.CharField(max_length=100)
    type = models.CharField(max_length=30)
    brand = models.CharField(max_length=50)
    price = models.IntegerField()

Run the makemigrations command to create a new migration based on the changes made by the models.

$ python3 manage.py makemigrations queryapp

Run the migrate command to execute the SQL commands and create all tables in the database that are defined in the models.py file.

$ python3 manage.py migrate

Modify the content of the admin.py file with the following content. Here, the models’ Product class is registered by using the register() method to display the products tables in the Django administration dashboard.

admin.py

# Import admin module
from django.contrib import admin
# Import Product model
from .models import Product

# Register Product model
admin.site.register(Product)

Create a template file named productList.html inside the queryapp/templates/ with the following script. This script will display all data of products table in tabular form with a search box. The user will be able to search the particular records from the products table by using the search form. for loop is used in the script to iterate the data passed from the views.py file.

productList.html

<html>
<head>
  <title>
    Django QuerySet Tutorial
  </title>

  <style>
    th { text-align:left; color:blue; }
    table, th, td { border: 1px solid;}
    h1{ color:green;}
    #name{ width:350px;}
  </style>
</head>
<body>
<center><h1 style="margin-left:20px;">Searching Product</h1>
<form method="get" action="">
  {% csrf_token %}
  Search Product: <input name="src" type="text" placeholder="Search..." value="">
</form>
</center>
<center>
  <table>
   <tr>
    <th>ID</th><th id="name">Name</th><th>Brand</th><th>Price</th>
    </tr>
    {% for product in object_list %}
    <tr>
       <td>{{product.id}} </td> <td>{{product.name}}</td> <td>{{product.brand}}</td><td
style="text-align:right">${{product.price}}</td>
    </tr>
    {% endfor %}
  </table>
</center>
</body>
</html>

Modify the content of the views.py file with the following script. The model and template names are defined in the ProductList class. get_queryset() method of the class is defined in the script to filter the data based on the content submitted by the search box of the template. Product.objects.all() method returns all records of the products table. request.GET.keys() method is used in the script to check any data is submitted by the search form. If this method returns true, then the request.GET.get(‘src’) method is used to check the submitted value is empty or not. If this method returns a non-empty value, then the value will be stored in the variable, keyword, and it will be used for filtering the data based on the brand and type fields from the products table.

views.py

# Import ListView module
from django.views.generic import ListView
# Import Product module
from .models import Product
# Import Q module
from django.db.models import Q

# Define class for Querying data
class ProductList(ListView):
    # Define model
    model = Product
    # Define template
    template_name = 'productList.html'


    def get_queryset(self):
        # Set the default query set
        queryset = Product.objects.all()
        # Check the form value is submitted or not
        if self.request.GET.keys():
            # Check the search keyword
            if self.request.GET.get('src') != '':
                keyword = self.request.GET.get('src')
                # Set the query set based on search keyword
                queryset = Product.objects.filter(Q(brand=keyword.capitalize()) | Q(type=keyword.capitalize()))
        return queryset

Modify the content of the urls.py file with the following script. In the script, the ‘searchPro/’ path is defined to call the ProductList.as_view() method that will send all data and the filtered data of the products table to the template file.

urls.py

# Import admin module
from django.contrib import admin
# Import path and include module
from django.urls import path

# Import SearchEmployee module
from queryapp.views import ProductList

urlpatterns = [
    # Define the path for admin
    path('admin/', admin.site.urls),

    # Define the path to search product
    path('searchPro/', ProductList.as_view()),

Add records into the table:

Open the Django Administration page and add some records into the products table to apply the queryset on then. Here, five records have been inserted.

All records of the products with the search box will be displayed in the browser after executing the following URL.

http://localhost:8000/searchPro


All the shampoo products displayed if the product type, ‘shampoo‘ will be searched in the search box.

The milk powder products of the Fresh brand will be displayed if the product brand, ‘fresh‘ will be searched in the search box.

Conclusion:

The way of filtering the data of a simple database table by using queryset has explained in this tutorial. The data can be filtered in different ways. The readers will understand using a queryset to filter or search data in the browser after reading this tutorial.

]]>
Creating a Django App on Ubuntu Server https://linuxhint.com/create_django_app_ubuntu/ Tue, 11 Jun 2019 17:34:08 +0000 https://linuxhint.com/?p=41992 Django is a common platform for developing websites, web applications and web APIs. There are many advantages to using the Django framework for your project as your tool and if you’re not sure it’s the right fit, you need only to look to the many big name brands using Django in their stack.

Deploying Django to a production environment for the first time can be a daunting task. Often, developers will launch a Linux instance on the cloud for their production environment.

In this tutorial, we’ll show you how to launch Django in production, using a fresh Ubuntu instance.

We’ll assume that all of your editing is done on the server, and that you’re running the commands as root.

For this tutorial, we’re using Ubuntu 18.04.2 LTS

Creating a user for the project

We’ll create a new user, django, for running our application. This provides a slight security benefit.

To create the new user:

useradd -m django

The -m flag creates a new home directory: /home/django.

Setting up the Python environment

First things first: update your package lists with apt-get update

Ubuntu 18.04 ships with Python 3.6, but it doesn’t ship with pip, which you’ll need to install your dependencies.

apt-get install python3-pip

Now that we have pip, let’s create a virtual environment. Virtual environments help to avoid conflicts with Python packages used by Linux.

pip3 install virtualenv
cd /home/django
virtualenv env

Now you’ve created a virtual Python 3.6 environment in the /home/django/env folder which can be activated with the following command:Now that we have pip, let’s create a virtual environment. Virtual environments help to avoid conflicts with Python packages used by Linux.

source /home/django/env/bin/activate

Setting up the Django project

For this tutorial, we’ll create a temporary Django project. If you’re deploying your own code, you’ll have to upload it to the server instead. We’ll be operating in the home directory, /home/django.Setting up the Django project

Let’s create the Django project:

cd /home/django
source env/bin/activate
pip install django
django-admin startproject tutorial

Verify things are working by running:

cd tutorial
python manage.py runserver 0.0.0.0:80

Our Ubuntu instance is running at 178.128.229.34 so we’ll connect to http://178.128.229.34.Verify things are working by running:

You’ll likely see something like this:

To fix this, we’ll edit /home/django/tutorial/tutorial/settings.py. Find  ALLOWED_HOSTS = [] and set it to:

ALLOWED_HOSTS = [
'178.128.229.34' # replace this with your server's IP address
 or the domain name you're using to connect
]

Now let’s go back to http://178.128.229.34:

Great! We’re online!

Setting up PostgreSQL, the database

By default, Django uses a SQLite3 database. Unfortunately, SQLite3 does not allow concurrent writes. If your website only ever has one user editing data, and the rest of the visitors are just reading pages, then this might be appropriate. But if you have multiple people editing data at the same time you likely want to use a different backend.

Common choices are PostgreSQL and Mysql. We’ll go with PostgreSQL for this tutorial.

Start by installing PostgreSQL:

apt-get install postgresql

Then launch psql, a database shell. By default, only the postgres user is able to connect to the database so we’ll first have to authenticate as that user:

su - postgres
psql

Next, we need a database and a user to access that database:

create database tutorial;
create user tutorial_user with encrypted password 'tutorial_password';
grant all privileges on database tutorial to tutorial_user;

Now, type exit or press Ctrl-D twice: once to exit psql, and once to log out of the postgresuser’s shell.

Great! Now we have our database and user set up. Let’s verify we can log in to our database.

We’ll try to open up a database shell, this time logging in to the database we created with the user we created:

psql -Ututorial_user -dtutorial -h127.0.0.1 -W

At the prompt, enter the password we created: tutorial_password.

If you see a database shell, you’ve been successful. If you see any errors, you’ll have to go back and figure out what’s wrong.

Connecting Django to the database

To get Django connected to the database, we first need to install the Python PostgreSQL adapter:

pip install psycopg2-binary

Then, let’s open up /home/django/tutorial/tutorial/settings.pyand configure the connection.

Find your current database connection; if you didn’t modify it, it might look something like this:

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}

To connect to PostgreSQL, we’ll replace it with the following:

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'tutorial',
'USER': 'tutorial_user',
'PASSWORD': 'tutorial_password',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}

Let’s test the connection:

cd /home/django/tutorial
python manage.py runserver 0.0.0.0:80

You should again be able to visit your website (for us at http://178.128.229.34/, but replace that with your IP or hostname).

If all is well, we can continue.

Setting up nginx, the web server

When you run python manage.py runserver, you’re using Django’s development server. This is great for local development, but as with SQLite3, it’s not really suited for production.

Common choices for production web servers are nginx and Apache. For this tutorial, we will use nginx.

Install nginx using the following:

apt-get install nginx

Now, if everything has worked well, nginx should be running on port 80. Go ahead and check out you website; you should see:

Great, so nginx is up and running! Next we’ll need to configure it to communicate with Django. Open up the nginx configuration file, located at /etc/nginx/sites-available/default. Let’s replace the file with the following:

upstream django {
server 127.0.0.1:8000;
}

server {
listen 80;

location / {
try_files $uri @send_to_django;
}

location @send_to_django {
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://django;
}
}

Test the configuration file by running nginx -t. If everything is ok, we can reload by running nginx -s reload.

Now, if you visit your site you will see the following:

Whenever you see this, it means that nginx was unable to pass the request to the upstream process. At the moment, it’s because it’s trying to pass the request to 127.0.0.1:8000 but there is no process listening at that address.

Let’s start the Django development server and try again:

cd /home/django/tutorial
python manage.py runserver 127.0.0.1:8000

and again visit your website. You should see your Django application.

Mounting Django on Gunicorn

Remember, we don’t want to use our Django development server in production. Instead, we’ll use a Web Server Gateway Interface (WSGI) server to run Django. Nginx will pass the request to the WSGI server, which is running Django.

Common choices for a WSGI server are Gunicorn and uWSGI. For this tutorial we will use Gunicorn.

Let’s install Gunicorn:

pip install gunicorn

Next, we can start gunicorn as follows:

cd /home/django/tutorial
gunicorn tutorial.wsgi

Now you should be able to visit your website and see your application running properly.

Running Gunicorn as a service

There are a few issues with running gunicorn like this:

  1. If we close the SSH session, the gunicorn process will stop.
  2. If the server reboots, the gunicorn process won’t start.
  3. The process is running as root. If hackers find an exploit in our app’s code, they’ll be able to run commands as root. We don’t want this; but that’s why we created the djangouser!

To solve these problems, we’re going to run Gunicorn as a systemd service.

cd /home/django
mkdir bin
cd /home/django/bin
touch start-server.sh

In start-server.sh:

cd /home/django
source env/bin/activate
cd tutorial
gunicorn tutorial.wsgi

Now you can test the script:

cd /home/django/bin
bash start-server.sh
# visit your website, it should be running

Now we create the systemd service for Gunicorn. Create /etc/systemd/system/gunicorn.serviceas follows:

[Unit]
Description=Gunicorn
After=network.target

[Service]
Type=simple
User=django
ExecStart=/home/django/bin/start-server.sh
Restart=on-failure

[Install]
WantedBy=multi-user.target

Now, let’s enable the service & start it

systemctl enable gunicorn
systemctl start gunicorn

You should be able to see your website at the moment.

We can turn gunicorn off as follows:

systemctl stop gunicorn

And you should see a 502 Bad Gateway.

Finally, let’s check the boot cycle:

systemctl start gunicorn
reboot now

When your machine comes back online, you should see your website is up.

Static files

If you visit the Django admin panel on your website at /admin/ (for us, it’s http://178.128.229.34/admin/), you’ll notice static files aren’t loading properly.

We’ll need to create a new folder for static files:

cd /home/django
mkdir static

Then, we tell Django that’s where it should put the static files by editing /home/django/tutorial/tutorial/settings.py, and adding:

STATIC_ROOT = '/home/django/static/'

Now we can gather the static files:

cd /home/django
source env/bin/activate
cd tutorial
python manage.py collectstatic

Finally, we need to tell nginx to serve those static files.

Let’s open up /etc/nginx/sites-available/default and add the following directly above your location / block:

location /static/ {
root /home/django;
try_files $uri =404;
}

The whole file should now look like this:

upstream django {
server 127.0.0.1:8000;
}

server {
listen 80;

location /static/ {
root /home/django;
try_files $uri =404;
}

location / {
try_files $uri @send_to_django;
}

location @send_to_django {
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://django;
}
}

We can reload the file using nginx -s reload

And voila! Your static files will now be working fully.

Conclusion

At this point, your Django app is working properly. If you have some special requirements, you might need to set up a cache like Redis or a message queue like Rabbit MQ. You might also want to set up continuous deployment as the deployment procedure might take a while.

Another important step is to take the appropriate steps to secure your Ubuntu machine. Otherwise, you might find your server misbehaving!

Good luck!

]]>