Skip to content
Irvine Sunday edited this page Feb 7, 2024 · 16 revisions

Introduction:

Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. It follows the model-view-controller (MVC) architectural pattern. This pattern separates an application into three interconnected components, each with its own distinct responsibility:

Model:

  • The Model represents the application's data and business logic.
  • It is responsible for managing the data, processing user inputs, and responding to requests from the View and Controller.
  • The Model notifies the View of any changes in the data, allowing the View to update itself accordingly.

View:

  • The View is responsible for presenting the data to the user and receiving user inputs.
  • It displays the information from the Model to the user and sends user inputs to the Controller for processing.
  • The View is passive and doesn't directly interact with the Model. Instead, it observes changes in the Model and updates its presentation accordingly.

Controller:

  • The Controller handles user inputs and updates the Model accordingly.
  • It acts as an intermediary between the View and the Model, processing user actions and updating the data in the Model.
  • The Controller also updates the View based on changes in the Model.

Install Django:

Django comes as a python package and can therefore be installed in any python environment.
Ensure you have python installed
create an isolated python environment. Python comes with the venv library which provides support for creating lightweight virtual environments. Having an isolated Python environment enables you to use different package versions for different projects. Create an isolated environment with the following command:

python -m venv my_env

Activate your environment:

my_env/bin/activate

The shell prompt will include the name of the active environment enclosed in parentheses. You can deactivate your environment at any time with the deactivate command.
Use the following command to install Django using pip:

pip install django

Django will be installed in the Python site-packages/ directory of your virtual environment. to test whether Django has been successfully installed:

  • Run python on a terminal
  • import Django
  • ccheck its version
>>> import django
>>> django.get_version()
# '3.04'

Create a Django Project:

Use the following command to create a new Django project:

django-admin startproject mysite

This will a Django project with the name mysite. The project structure generated looks like this:

mysite/   
   manage.py  
   mysite/  
      __init__.py   
      asgi.py  
      wsgi.py  
      settings.py  
      urls.py

manage.py:
This is a command-line utility that allows you to interact with various aspects of the Django project, such as running development server, creating database tables, and more.
It's used to perform administrative tasks and manage the Django project.

__init__.py:
An empty file that tells Python to treat the mysite directory as a python module.
It can be empty or may contain package-level initialization code.

settings.py:
Configuration settings.
It includes settings related to databases, middleware, templates, static files, and more.
Developers customize this file to configure their Django project according to their requirements.

urls.py:
This file contains the URL patterns for your Django project.
It defines how URLs are mapped to views in your application.
URL patterns specify the structure of URLs and the views that should handle them.

asgi.py:
This file is used for ASGI (Asynchronous Server Gateway Interface) deployment.
ASGI is a specification for asynchronous web servers to communicate with web applications.

wsgi.py:
This file is used for WSGI (Web Server Gateway Interface) deployment.
WSGI is a specification that describes how a web server communicates with web applications.

Database Configuration:

The settings.py file contains configurations for your Django project. One crucial aspect is the database configuration. By default, Django is configured to use SQLite. If you plan to use a different database, you can modify the DATABASES setting in this file.
Example with MySQL:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'big4auction',
        'USER': 'root',
        'PASSWORD': 'I$a80899819',
        'PORT': 3306,
        'HOST': '127.0.0.1'
    }
}

Example with PostgreSQL:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydatabase',
        'USER': 'mydatabaseuser',
        'PASSWORD': 'mypassword',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

Migrate Database:

After configuring the database, you need to apply migrations to create the necessary database tables. Run the following commands in your terminal:

python manage.py makemigrations
python manage.py migrate

By applying migrations, the tables for the initial applications are created in the database.

Create a Django App:

Django projects are made up of apps, which are modular components that can be reused in other projects.
To create a new app, run:

python manage.py startapp myapp

This will create a new directory called myapp with its own set of files and folders.

Registering the App:

Registering an app in the Django project involves adding the app's name to the INSTALLED_APPS setting in the settings.py file. This step is essential for Django to recognize and include the app in the project.
Open the settings.py file in your Django project (mysite/settings.py). Locate the INSTALLED_APPS setting, and add the name of your app to the list. For example:

INSTALLED_APPS = [
    # ...
    'myapp',
    # ...
]

App File Structure

Here is an overview of the typical file structure of a Django app:

myapp/
    __init__.py
    admin.py
    apps.py
    migrations/
        __init__.py
    models.py
    tests/
        __init__.py
        test_models.py
    views.py

__init__.py:
An empty file that indicates to Python that the directory should be treated as a Python package.

admin.py:
This file is used for registering models with the Django admin interface. You can customize how your models appear in the admin panel by defining classes here.

apps.py:
Configuration for the app. It may include metadata about the app and can be customized if needed.

migrations/:
This directory contains database migration files generated by Django when you run python manage.py makemigrations. Migrations are used to evolve the database schema over time as your models change.

models.py:
This is where you define the data models for your app. Models represent database tables and define the fields and behaviors of the data.

tests/: This directory is meant for storing test files. You can create unit tests for your app to ensure its functionality.

views.py:
Here, you define the views that handle HTTP requests and return HTTP responses. Views process user input, interact with models, and return the appropriate response, often in the form of HTML content.

In addition to these core files and directories, you might also see:

static/:
This directory is used to store static files (CSS, JavaScript, images) specific to the app.

templates/:
Used for storing HTML templates associated with your app's views. Django uses this directory to look for templates when rendering views.

middleware.py:
If your app includes custom middleware, you can place it in this file.

urls.py:
This file is used to define the URL patterns for your app. It specifies which views should be called for specific URLs.

forms.py:
Optionally used for defining Django forms associated with your models or views.

apps/:
If you have multiple apps in your project, you can create a directory called apps/ within your project and place each app in its own subdirectory. This is a common practice for larger projects to keep the project structure organized.

Run The Server:

Django comes with a lightweight web server to run your code quickly, without needing to spend time configuring the production server.
When you run the django development server, it keeps checking for changes in your code. It reloads automatically, freeing you from manually reloading it after code changes. However it might not notice some actions such as adding new files to the project, so you will have to restart the server manually in these cases.
Start the development server by typing the following command:

python manage.py runserver

At this point, open http://127.0.0.1:8000/ in your browser. You should see a page stating that the project is successfully running.
If you look at the console, you will see that a GET request was performed by your browser.
Each Http request and any errors that occur while running the development server will also appear in the console.
You can run the Django development server on a custom host and port:

python manage.py runserver 127.0.0.1:8001

This server is only intended for development and is not suitable for production use. In order to deploy Django in a production environment, you should run it as a WSGI application using a web server such as Apache, Gunicorn, uWSGI etc or as an ASGI application using a server like Uvicorn or Daphne.

Create a Simple View:

Open views.py in your app directory (myapp/views.py).
Define a simple view function:

from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, Django!")

Create URLs:

Create a URL pattern for this view in urls.py (in your app directory)

from django.urls import path
from .views import index

urlpatterns = [
    path('', index, name='index'),
]

Include the app's URLs in the project's urls.py (located in the project's main directory):

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('myapp.urls')),  # Include the app's URLs
]

Important Settings

DEBUG:
This setting controls whether Django is in debug mode. It should be set to False in a production environment for security reasons (avoids exposing sensitive project related data).
If its set to True, Django will display displaye detailed error pages when an uncaught exception is thrown by your application.

ALLOWED_HOSTS:
Specifies a list of valid host/domain names for the production server. Set it to your domain when deploying to production.

DATABASES:
This setting defines the database configuration. Adjust the database engine, name, user, password, host, and port as per your requirements.
There must always be a default database. The default confuguration uses SQLite3 database.

TIME_ZONE:
Set your project's time zone. For example, 'UTC' or 'America/New_York'.

STATIC_URL and STATIC_ROOT:
These settings define the URL and root directory for static files (CSS, JavaScript, images). Ensure proper configuration for static file serving in production.

INSTALLED_APPS:
This setting tells Django which applications are active for this site.

MEDIA_URL and MEDIA_ROOT:
Similar to static files, these settings define the URL and root directory for media files (uploads). Configure for production deployment accordingly.

TEMPLATES:
This setting defines the configuration for template engines. The default is usually fine, but you can customize it based on your needs.

MIDDLEWARE:
Middleware is a way to process requests globally before they reach the view. Django includes various built-in middleware. Review and modify as needed.

AUTHENTICATION_BACKENDS:

LANGUAGE_CODE and USE_TZ:
Set the language code and whether to use time zone support.

ROOT_URLCONF:
Specifies the root URL configuration for the project. By default, it points to 'mysite.urls'.

WSGI_APPLICATION and ASGI_APPLICATION: These settings point to the application object used to run the ASGI/WSGI server. Typically, they point to 'mysite.wsgi.application' and 'mysite.asgi.application'.

Creating Models:

A model is a python class that subclasses django.db.models.Model in which each attribute represents a database field.
Django will create a table for each model defined in the models.py file.
When you create a model, django will provide you with a practical API to query objects in the datanbase easily.

from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
from django.template.defaultfilters import slugify

class Post(models.Model):
    title = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200, unique=True, null=True, blank=True)
    content = models.TextField()
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    published_date = models.DateTimeField(default=timezone.now)
    created_date = models.DateTimeField(auto_now_add=True)
    modified_date = models.DateTimeField(auto_now=True)

    def save(self, *args, **kwargs):
        # Auto-generate slug when saving
        if not self.slug:
            self.slug = slugify(self.title)
        super().save(*args, **kwargs)

    def __str__(self):
        return self.title

Let's break down the key components of this model:

title (CharField):
Represents the title of the blog post.
It is a character field with a maximum length of 200 characters.

slug (SlugField):
Represents a URL-friendly version of the post title.
SlugField is often used for creating SEO-friendly URLs.
unique=True ensures that each post has a unique slug.
null=True and blank=True allow the slug to be optional.

content (TextField):
Represents the main content of the blog post.
It is a text field, suitable for longer content.

author (ForeignKey to User model):
Represents the author of the blog post.
ForeignKey establishes a many-to-one relationship with the built-in User model.
on_delete=models.CASCADE specifies that if the referenced user is deleted, the corresponding posts should also be deleted.

published_date (DateTimeField with default value): Represents the date and time when the post is published.
DateTimeField is used for storing date and time information.
default=timezone.now sets the default value to the current date and time.

created_date and modified_date (DateTimeFields with auto values):
created_date represents the date and time when the post was created.
modified_date represents the date and time when the post was last modified.
auto_now_add=True sets created_date to the current date and time when the post is created.
auto_now=True updates modified_date to the current date and time whenever the post is saved.

save method:
Overrides the default save method to auto-generate the slug if it's not provided.
The slugify function from django.template.defaultfilters is used to create a URL-friendly version of the title.
super().save(*args, **kwargs) ensures that the overridden save method of the parent class (models.Model) is called.

__str__ method:
Defines a human-readable representation of the model instance.
In this case, it returns the title of the blog post.

Field Types:

In Django models, various field types are used to define the type of data that can be stored in a particular field of a model. Here are some commonly used field types in Django models:

CharField:
Represents a short text field (character field).
Usage: models.CharField(max_length=255)

TextField:
Represents a longer text field.
Usage: models.TextField()

IntegerField:
Represents a field for storing integers.
Usage: models.IntegerField()

FloatField:
Represents a field for storing floating-point numbers.
Usage: models.FloatField()

DecimalField:
Represents a field for storing decimal numbers with a fixed number of decimal places.
Usage: models.DecimalField(max_digits=5, decimal_places=2)

DateField:
Represents a field for storing dates.
Usage: models.DateField()

TimeField:
Represents a field for storing times.
Usage: models.TimeField()

DateTimeField:
Represents a field for storing both date and time.
Usage: models.DateTimeField()

BooleanField:
Represents a field for storing Boolean (True/False) values.
Usage: models.BooleanField()

EmailField:
Represents a field for storing email addresses. It includes validation for ensuring the input conforms to a typical email format.
Usage: models.EmailField()

ImageField:
Represents a field for storing image files.
Usage: models.ImageField(upload_to='images/')

FileField:
Represents a field for storing any type of file.
Usage: models.FileField(upload_to='files/')

URLField:
Represents a field for storing URLs.
Usage: models.URLField()

SlugField:
Represents a field for storing a short label that can be used in a URL.
Usage: models.SlugField()

ForeignKey:
Represents a many-to-one relationship to another model. It is used to create a foreign key in the database. Usage: models.ForeignKey(OtherModel, on_delete=models.CASCADE)

ManyToManyField:
Represents a many-to-many relationship to another model. It is used to create a many-to-many relationship table in the database. Usage: models.ManyToManyField(OtherModel)

OneToOneField:
Represents a one-to-one relationship to another model. It is used to create a one-to-one relationship in the database. Usage: models.OneToOneField(OtherModel, on_delete=models.CASCADE)

Creating an Admin Panel:

Creating and customizing the Django admin site allows you to provide an intuitive and powerful interface for managing your models without having to build a separate administration panel. Django's admin site is highly customizable, and you can tailor it to your specific needs. Let's go through the steps of creating and customizing an admin site for the Post model mentioned earlier.

Register the Model
Open your app's admin.py file (e.g., myapp/admin.py).
Register your Post model with the admin site.

from django.contrib import admin
from .models import Post

admin.site.register(Post)

This simple registration enables the default admin interface for the Post model.

Superuser Creation:
To access the admin site, you need a superuser account.
Run the following command and follow the prompts to create a superuser:

python manage.py createsuperuser

Customizing the Admin Interface:

from django.contrib import admin
from .models import Post

class PostAdmin(admin.ModelAdmin):
    # Fields to display in the list view of the admin site
    list_display = ('title', 'author', 'published_date', 'modified_date')

    # Fields to enable search functionality in the admin site
    search_fields = ('title', 'content')

    # Fields to enable filters on the right side of the list view
    list_filter = ('published_date', 'author')

    # Grouping fields in the detail view of the admin site
    fieldsets = [
        ('Post Information', {'fields': ['title', 'content', 'author']}),
        ('Date Information', {'fields': ['published_date', 'modified_date']}),
    ]

    # Customize the appearance of the detail view
    readonly_fields = ('published_date', 'modified_date')
    date_hierarchy = 'published_date'
    ordering = ('-published_date',)

    # Actions to perform on selected posts in the list view
    actions = ['make_published']

    # Custom action to mark selected posts as published
    def make_published(self, request, queryset):
        queryset.update(published_date=timezone.now())
    make_published.short_description = "Mark selected posts as published"

# Register the Post model with the customized admin class
admin.site.register(Post, PostAdmin)

list_display:
This attribute specifies the fields to display in the list view of the admin site.
In this example, it includes the post title, author, published date, and modified date.

search_fields:
This attribute enables a search box in the admin site for specified fields.
It allows administrators to quickly search for posts based on their title or content.

list_filter:
This attribute adds filters on the right side of the list view.
It allows administrators to filter posts based on published date or author.

fieldsets:
This attribute groups fields in the detail view of the admin site.
It creates two sections: "Post Information" and "Date Information," grouping related fields together.

readonly_fields:
This attribute specifies fields that should be read-only in the detail view.
In this example, published_date and modified_date are read-only.

date_hierarchy: This attribute adds a date-based drilldown navigation by year, month, and day. It enhances the browsing experience in the admin site.

ordering:
This attribute specifies the default ordering of posts in the list view.
It orders posts by published date in descending order.

actions:
This attribute defines custom actions that can be performed on selected posts in the list view.
In this example, there's a custom action named make_published.

make_published:
This is a custom action method that marks selected posts as published.
It's accompanied by a short_description attribute that provides a human-readable name for the action.

Add Static File

Adding static files to a Django project involves serving and managing static resources such as CSS, JavaScript, and images.
Organize Static Files:
Create a static directory in your Django app to store static files.

mysite/
├── manage.py
└── mysite/
    ├── __init__.py
    ├── asgi.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py
    └── myapp/
        ├── static/
        │   ├── css/
        │   │   └── styles.css
        │   ├── js/
        │   └── img/
        └── ...

Configure Static Files in Settings:
Open settings.py and add the following lines to configure static files.

# settings.py

import os

# ...

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_ROOT = BASE_DIR / 'productionfiles'
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'myapp/static')]

Here, STATIC_URL specifies the base URL for serving static files, and STATICFILES_DIRS is a list of directories where Django will look for static files.

Link Static Files in Templates:

<!-- myapp/templates/myapp/base.html -->
{% load static %}
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}MyApp{% endblock %}</title>
    <link rel="stylesheet" href="{% static 'css/styles.css' %}">
</head>
<body>
    {% block content %}{% endblock %}
</body>
</html>

Use the {% static %} template tag to generate the URL for a static file.
If you just want to play around, and not going to deploy your work, you can set DEBUG = True in the settings.py file, and the example above will work.
If you plan to deploy your work, you should set DEBUG = False in the settings.py file. The example above will fail, because Django has no built-in solution for serving static files, but there are other ways to serve static files.
You will have install a third-party library in order to handle static files.
When using DEBUG = False you have to specify which host name(s) are allowed to host your work. You could choose '127.0.0.1' or 'localhost' which both represents the address of your local machine.
We choose '*', which means any address is allowed to host this site. This should be changed into a real domain name when you deploy your project to a public server.

WhiteNoise:
A Python library, built for serving static files.
To install WhiteNoise in your virtual environment, type the command below:

pip install whitenoise

To make Django aware of you wanting to run WhitNoise, you have to specify it in the MIDDLEWARE list in settings.py file:

MIDDLEWARE = [
    #.....
    'whitenoise.middleware.WhiteNoiseMiddleware',
]

Collect Static Files:
To collect all necessary static files for your project, start by specifying a STATIC_ROOT property in the settings.py file.
This specifies a folder where you want to collect your static files.
You can call the folder whatever you like, we will call it productionfiles:

#settings.py

STATIC_ROOT = BASE_DIR / 'productionfiles'
STATIC_URL = 'static/'

You could manually create this folder and collect and put all static files of your project into this folder, but Django has a command that do this for you:

py manage.py collectstatic

Django ORM:

Django's Object-Relational Mapping (ORM) is a powerful feature that allows developers to interact with a relational database using Python objects. The Django ORM abstracts the underlying database structure, making it easier to perform database operations without writing raw SQL queries.
Django ORM is based on QuerySets. A QuerySet is a collection of database queries to retrieve objects from a database.
Querysets are a Django ORM feature that allows you to retrieve, filter, and manipulate data from the database using a Pythonic syntax.

Examples:

# Retrieve all posts
all_posts = Post.objects.all()

# Filter posts based on a condition
recent_posts = Post.objects.filter(pub_date__gte=datetime.now() - timedelta(days=7))

# Order posts by publication date
ordered_posts = Post.objects.order_by('-pub_date')

CRUD Operations:

Django ORM supports the basic CRUD operations (Create, Read, Update, Delete) on database records.
Create:

new_post = Post(title='New Post', content='This is the content.')
new_post.save()

Read:

post = Post.objects.get(id=1)

Update:

post = Post.objects.get(id=1)
post.title = 'Updated Title'
post.save()

Delete:

post = Post.objects.get(id=1)
post.delete()

Aggregation and Annotation:

Django ORM provides aggregation functions like count(), sum(), avg(), etc., for complex queries.

from django.db.models import Count

# Count the number of posts per author
author_post_count = Post.objects.values('author').annotate(post_count=Count('id'))

Transactions:

Django ORM supports database transactions, ensuring that a series of operations either succeed or fail as a single unit.

from django.db import transaction

with transaction.atomic():
    # Perform multiple operations as part of a transaction
    post1 = Post(title='Post 1', content='Content 1')
    post1.save()

    post2 = Post(title='Post 2', content='Content 2')
    post2.save()

Relationships:

Django ORM supports various relationships between models, including ForeignKey (many-to-one), OneToOneField (one-to-one), and ManyToManyField (many-to-many).

Raw SQL Queries:

While Django encourages the use of its ORM, it also provides the option to execute raw SQL queries when necessary.
Example:

from django.db import connection

with connection.cursor() as cursor:
    cursor.execute("SELECT * FROM myapp_post WHERE title LIKE %s", ['%keyword%'])
    results = cursor.fetchall()

Using raw() Method:
Django provides a raw() method for executing raw SQL queries and returning model instances.

results = Post.objects.raw("SELECT * FROM myapp_post WHERE title LIKE %s", ['%keyword%'])

Database Configuration:

Django ORM supports multiple database backends, including PostgreSQL, MySQL, SQLite, and Oracle. Database configuration is specified in the settings.py file.

Database Indexing:

Django ORM allows you to define indexes on specific fields for better query performance.
Example:

class Post(models.Model):
    title = models.CharField(max_length=200, db_index=True)
    content = models.TextField()

QuerySets:

A QuerySet is a collection of data from a database.
A QuerySet is built up as a list of objects.
Django QuerySets are a powerful and expressive feature of the Django ORM that allows you to interact with the database using Python. QuerySets abstract the underlying SQL queries, making it easier to retrieve, filter, and manipulate data from the database.

Retrieving All Objects:

all_posts = Post.objects.all()

Values() Method:
It allows you to return each object as a Python dictionary.

all_posts = Post.objects.all().values()

values_list() Method:
It allows you to return only the columns that you specify.

mydata = Member.objects.values_list('firstname')

Filtering Objects:
You can filter objects based on specific conditions
Returns specific rows/records
Django supports various lookup types (e.g., exact, iexact, contains, icontains, gt, lt, etc.) for precise filtering.

recent_posts = Post.objects.filter(pub_date__gte=datetime.now() - timedelta(days=7))

The filter() method takes the arguments as **kwargs (keyword arguments), so you can filter on more than one field by separating them by a comma. This performs an AND SQL query

mydata = Member.objects.filter(lastname='Refsnes', id=2).values()

To perform an OR SQL query:
We can use multiple filter() methods, separated by a pipe | character. The results will merge into one model.

ydata = Member.objects.filter(firstname='Emil').values() | Member.objects.filter(firstname='Tobias').values()

Another common method is to import and use Q expressions:

from django.db.models import Q
mydata = Member.objects.filter(Q(firstname='Emil') | Q(firstname='Tobias')).values()

Chaining Filters:
Multiple filters can be chained together to create more complex queries.

filtered_posts = Post.objects.filter(category='Django').filter(pub_date__year=2022)

Alternatively, you can use the Q object for complex OR queries.

from django.db.models import Q

filtered_posts = Post.objects.filter(Q(category='Django') | Q(category='Python'))

Slicing:
You can use Python slicing to limit the number of results retrieved.

first_five_posts = Post.objects.all()[:5]

Ordering:
The order_by() method allows you to specify the order in which results should be returned.

ordered_posts = Post.objects.all().order_by('-pub_date')

You can order by multiple fields or use the - prefix for descending order.

mydata = Member.objects.all().order_by('lastname', '-id').values()

Updating Records:

Post.objects.filter(category='Old').update(category='New')

Deleting Records:

old_posts = Post.objects.filter(category='Old')
old_posts.delete()

QuerySet Optimization:
select_related() is used to fetch related objects in a single query instead of separate queries for each relationship. In the example, it fetches the Author object related to each Post in a single query.

# Using select_related for ForeignKey relationship
posts = Post.objects.select_related('author').filter(category='Django')

prefetch_related() is used to fetch related objects in a separate query, improving performance when dealing with ManyToManyField relationships. In the example, it fetches all the Post objects related to each Author in a single query.

# Using prefetch_related for ManyToManyField relationship
authors = Author.objects.prefetch_related('posts').filter(name='John Doe')

Field Lookups:

To make specific where clauses in Django, use "Field lookups".
Field lookups are keywords that represents specific SQL keywords.
All Field lookup keywords must be specified with the fieldname, followed by two underscore characters, and the keyword.

contains:
Contains the phrase.

matching_posts = Post.objects.filter(title__contains='Django')

icontains:
Same as contains, but case-insensitive.

matching_posts = Post.objects.filter(title__icontains='django')

date:
Matches a date.

matching_posts = Post.objects.filter(pub_date__date=date(2022, 1, 1))

day: Matches a day of the month (1-31) for date fields.

matching_posts = Post.objects.filter(pub_date__day=15)

endswith:
Ends with.

matching_posts = Post.objects.filter(title__endswith='Tutorial')

iendswith:
Same as endswith, but case-insensitive.

matching_posts = Post.objects.filter(title__iendswith='tutorial')

exact:
An exact match.

matching_posts = Post.objects.filter(id__exact=1)

iexact: Same as exact, but case-insensitive.

matching_posts = Post.objects.filter(title__iexact='django tutorial')

in:
Matches one of the values.

matching_posts = Post.objects.filter(category__in=['Django', 'Python'])

isnull:
Matches NULL values

null_posts = Post.objects.filter(author__isnull=True)

gt:
Greater than.

greater_than_posts = Post.objects.filter(views__gt=100)

gte:
Greater than or equal to.

greater_than_or_equal_posts = Post.objects.filter(views__gte=100)

hour:
Matches an hour for datetime fields.

matching_posts = Post.objects.filter(pub_date__hour=12)

lt:
Less than.

less_than_posts = Post.objects.filter(views__lt=100)

lte:
Less than or equal to.

less_than_or_equal_posts = Post.objects.filter(views__lte=100)

minute:
Matches a minute for datetime fields.

matching_posts = Post.objects.filter(pub_date__minute=30)

month:
Matches a month for date fields.

matching_posts = Post.objects.filter(pub_date__month=6)

quarter:
Matches a quarter of the year (1-4) for date fields.

matching_posts = Post.objects.filter(pub_date__quarter=3)

range: Match between.

range_posts = Post.objects.filter(views__range=(50, 100))

regex:
Matches a regular expression.

regex_posts = Post.objects.filter(title__regex=r'^[A-Z]')

iregex:
Same as regex, but case-insensitive.

iregex_posts = Post.objects.filter(title__iregex=r'^django')

second:
Matches a second for datetime fields.

matching_posts = Post.objects.filter(pub_date__second=0)

startswith:

matching_posts = Post.objects.filter(title__startswith='Django')

istartswith:
Same as startswith, but case-insensitive.

matching_posts = Post.objects.filter(title__istartswith='django')

time:
Matches a time for datetime fields.

matching_posts = Post.objects.filter(pub_date__time__hour=12, pub_date__time__minute=30)

week:
Matches a week number (1-53) for date fields.

matching_posts = Post.objects.filter(pub_date__week=25)

week_day:
Matches a day of the week (1-7), where 1 is Sunday.

matching_posts = Post.objects.filter(pub_date__week_day=1)

iso_week_day:
Matches an ISO 8601 day of the week (1-7), where 1 is Monday.

matching_posts = Post.objects.filter(pub_date__iso_week_day=1)

year:
Matches a year for date fields.

matching_posts = Post.objects.filter(pub_date__year=2022)

iso_year:
Matches an ISO 8601 year for date fields.

matching_posts = Post.objects.filter(pub_date__iso_year=2022)

Deployment

To deploy a project means to make it visible for other people on the internet.
we have made a Django project that runs locally on your computer. This is often called, "in development", and when we have deployed it, we call it "in production".
There are many providers out there that offers servers for Django projects. In this tutorial we will use the Amazon Web Services (AWS) platform, mainly because they offer a free solution that only requires you to create an AWS account.

Lock in Dependencies:
When you create a Django application, there are some Python packages that your project depends on.
Django itself is a Python package, and we have to make sure that the server where we deploy our project also has the Django package installed, and all the other packages your project requires.
Luckily there is a command for this as well, just run this command in the command view:

py -m pip freeze > requirements.txt

The result of the above command, is a file called requirements.txt being created in the project. The file contains all the packages that this project depends on
Now the hosting provider knows which packages to install when we deploy our project.

Provider-Specific Settings:
We have chosen AWS as our hosting provider, and Elastic Beanstalk as a service to deploy the Django project, and it has some specific requirements:
It requires that you create a folder on the root level of your project called .ebextensions
In the .ebextensions folder, create a file called django.config
Open the file and insert these settings:

 option_settings:
  aws:elasticbeanstalk:container:python:
    WSGIPath: my_tennis_club.wsgi:application

Zip Your Project:
To wrap your project into a .zip file, you cannot zip the entire project folder, but choose the files and folders manually.
The files to included in the .zip file are:

my_tennis_club
    .ebextensions/
    members/
    my_tennis_club/
    productionfiles/
    manage.py
    requirements.txt

With your file explorer, navigate to the project folder, select these files and folders, right-click and choose to create a zip file.
Now you have a .zip file of your project which you can upload to Elastic beanstalk: