fsd notes
fsd notes
Module-01
Web Framework
Django: High-level Python web framework for rapid development. Features include an ORM,
URL routing, template engine, admin interface, and strong security. Best for large, database-
driven applications.
Django is a high-level Python web framework that encourages rapid development and clean,
pragmatic design. It follows the model-template-view (MTV) architectural pattern, which is
similar to the model-view-controller (MVC) pattern used in other frameworks.
1. ORM (Object-Relational Mapping): Django provides a powerful ORM that allows you
to interact with databases using Python code instead of raw SQL.
2. URL Routing: It uses a URL configuration file to map URLs to views, making it easy to
create clean, SEO-friendly URLs.
3. Template Engine: Django has a template language that allows you to separate the design
from Python code.
4. Forms: It offers a form framework that handles rendering forms, validating user input,
and processing submitted data.
5. Authentication and Authorization: Django comes with a robust user authentication
system out of the box.
6. Admin Interface: It automatically generates an admin interface for your models, which
is great for managing your site's content.
7. Security Features: Django provides protection against common web vulnerabilities like
XSS, CSRF, SQL injection, etc.
The MVC design pattern is a software architecture pattern that separates an application
into three main components: Model, View, and Controller, making it easier to manage
and maintain the codebase.
It also allows for the reusability of components and promotes a more modular approach
to software development.
The Model View Controller (MVC) design pattern specifies that an application consists
of a data model, presentation information, and control information. The pattern requires
that each of these be separated into different objects.
How the MVC pattern works in general and how it can be related to Django in scope.
The MVC pattern is a software architecture pattern that separates data presentation from
the logic of handling user interactions (in other words, saves you stress:), it has been around as a
concept for a while, and has invariably seen an exponential growth in use since its inception. It has
also been described as one of the best ways to create client-server applications, all of the best
frameworks for web are all built around the MVC concept.
Model: This handles your data representation, it serves as an interface to the data stored in the
database itself, and also allows you to interact with your data without having to get perturbed with
all the complexities of the underlying database.
View: As the name implies, it represents what you see while on your browser for a web application
or In the UI for a desktop application.
Controller:
data i.e. it uses programmed logic to figure out what is pulled from the database through the model
and passed to the view, also gets information from the user through the view and implements the
given logic by either changing the view or updating the data via the model, To make it more
simpler, see it as the engine room.
Now that we understand the general concept of the MVC, understanding how it is implemented in
different frameworks can be another task as some frameworks (Django inclusive) like to
implement this same functionality in another way making it a bit difficult understanding what
actually happens at each layer.
implementation, the framework considers handling the Controller part of the MVC itself and
letting most of the good stuff happen in the Model-Template-View, this is why Django is mostly
referred to as the MTV framework.
Defines the database model for a book using Django's models. Model class.
Contains a Book class with two fields: name (CharField) and pub_date (DateField).
Represents the data layer of the application
class Book(models.Model):
name = models.CharField(max_length=50)
pub_date = models.DateField()
def latest_books(request):
book_list = Book.objects.order_by('-pub_date')[:10]
urlpatterns = patterns('',
(r'^latest/$', views.latest_books),
<html>
<head>
<title>Books</title>
</head>
<body>
<h1>Books</h1>
<ul>
{% endfor %}
</ul>
</body>
</html>
The components are loosely coupled, allowing for independent changes and enhancing
maintainability and scalability of the application.
Django Evolution
1. Origins: Django was created by Adrian Holovaty and Simon Willison in the fall of 2003.
They were web programmers at the Lawrence Journal-World newspaper in Lawrence,
Kansas, USA.
3. Organic Growth: Django grew organically from the real-world needs of the development
team. They initially built applications from scratch but soon realized the need for a
framework to streamline their process.
4. Framework Creation: Following the typical path of many web developers, the team
started refactoring their code to share common functionalities across applications. This led
to the creation of a framework.
5. Open-Source Release: In the summer of 2005, after developing the framework to a usable
state, the team, including Jacob Kaplan-Moss, decided to release it as open source software
in July 2005.
6. Name Origin: The framework was named Django after the jazz guitarist Django
Reinhardt.
8. Sweet Spot: Django's origins in a news environment influenced its design, making it
particularly well-suited for content sites with dynamic, database-driven information.
However, it's effective for building a wide range of dynamic websites.
1.8 LTS 1 Apr 2015 Native support for multiple template engines.Supported until
at least April 2018
1.9 1 Dec 2015 Automatic password validation. New styling for admin
interface.
1.10 1 Aug 2016 Full text search for PostgreSQL. New-style middleware.
1.11 LTS 1.11 LTS Last version to support Python 2.7.Supported until at least April
2020
2.0 Dec 2017 First Python 3-only release, Simplified URL routing syntax,
Mobile friendly admin.
In Django, views are Python functions that handle web requests and return web responses.
The views.py file is a convention for organizing view functions within a Django project.
To create a view, you define a Python function that takes an HttpRequest object as its first
parameter and returns an HttpResponse object.
In the provided example, the hello view function simply returns an HttpResponse object
with the text "Hello world".
# views.py
def hello(request):
Explanation:
In the URLconf, you import the view functions from views.py and map them to specific
URLs using regular expressions.
Each URL pattern is defined as a tuple containing a regular expression pattern and the
corresponding view function.
In the provided example, the URL pattern r'^hello/$' maps to the hello view function,
indicating that the view should be invoked when the URL /hello/ is requested.
# urls.py
urlpatterns = patterns('',
(r'^hello/$', views.hello),
Explanation:
Import necessary modules and the hello view function from views.py.
Define the urlpatterns variable, which is a mapping between URLs and the view functions.
Map the URL /hello/ to the hello view function. When a user visits this URL, Django will
call the hello function.
This setup tells Django to display "Hello world" when a user navigates to the /hello/ URL in the
browser.
Request Handling:
When a user makes a request to the Django server, Django's URL resolver examines the
requested URL and determines which view function to call based on the URLconf.
The view function receives an HttpRequest object as its first parameter, which contains
metadata about the request (e.g., headers, user agent, request method).
Although the hello view function doesn't utilize the HttpRequest object in this example, it's
a standard parameter for all view functions in Django.
Response Generation:
URL Mapping:
URL patterns defined in the URLconf serve as a mapping between URLs and view
functions.
Django uses regular expressions to match incoming URLs to patterns defined in the
URLconf.
When a matching URL is found, Django calls the corresponding view function to handle
the request and generate the response.
In a dynamic web application, URLs often contain parameters that influence the output of the page.
To demonstrate this, let's create a view in Django that displays the current date and time offset by
a certain number of hours. Instead of creating separate views for each hour offset, which would
clutter the URLconf, we can use a single view with a parameter in the URL to specify the hour
offset dynamically.
View Function:
We'll create a single view function named offset_datetime, which takes an hour offset as a
parameter and returns the current date and time offset by that number of hours.
# views.py
try:
offset_hours = int(offset)
dt = datetime.now() + timedelta(hours=offset_hours)
except ValueError:
2. URL Configuration:
We'll define a dynamic URL pattern with a parameter to specify the hour offset.
# urls.py
urlpatterns = patterns('',
(r'^time/plus/(?P<offset>\d+)/$', views.offset_datetime),
Explanation:
Definition Separation:
In Django, URLconfs are used to map URLs to view functions, specifying which view
function should be called for a given URL pattern.
The URL definitions and the implementation of view functions are kept separate, residing
in two distinct places within the Django project.
Interchangeability:
Loose coupling ensures that changes made to one component have minimal impact on
others.
If two pieces of code are loosely coupled, modifications to one piece won't require changes
to the other, promoting flexibility and maintainability.
Flexibility in Changes:
With Django's URLconfs, you can modify URL patterns without affecting the view
functions they map to, and vice versa.
For example, changing the URL pattern for a view (e.g., moving from /time/ to /current-
time/) can be accomplished without altering the view function itself.
Similarly, modifications to the view function's logic can be made independently of URL
changes.
Scalability:
Loose coupling enables easy scaling and extension of functionality within a Django project.
Adding new URLs or modifying existing ones can be done without disrupting other parts
of the application.
For instance, exposing a view function at multiple URLs can be achieved by editing the
URLconf without touching the view code.
Maintainability:
Separating URL definitions and view implementations promotes code clarity and makes it
easier to understand and maintain the project.
Developers can focus on specific tasks (e.g., URL routing or view logic) without needing
extensive knowledge of other components.
By leveraging loose coupling, Django enables developers to build web applications that are
flexible, modular, and easy to maintain.
This approach aligns with Django's philosophy of promoting rapid development and scalability
while ensuring code robustness and maintainability.
Errors in Django
When you deliberately introduce a Python error into your Django project, such as commenting out
critical lines of code, Django's error handling mechanisms come into play. Let's delve into how
Django's error pages help you debug and understand the issue:
Error Introduction:
By commenting out crucial lines of code in a view function, you intentionally introduce a
Python error into your Django project.
When you navigate to a URL that triggers the error, Django displays a detailed error page
with significant information about the exception.
At the top of the error page, Django presents key information about the exception,
including the type of exception, parameters, file name, and line number where the
exception occurred.
Additionally, Django provides the full Python traceback for the exception, displaying each
level of the stack trace along with the corresponding file, function/method name, and line
number.
Interactive Traceback:
Django's error page offers an interactive traceback, allowing you to click on any line of
source code to view several lines before and after the erroneous line, providing context for
better understanding.
You can also click on "Local vars" under any frame in the stack to view a table of all local
variables and their values at the exact point where the exception was raised, aiding in
debugging.
Django offers options to easily share the traceback with others for technical support. You
can switch to a copy-and-paste view or share the traceback on a public website like
http://www.dpaste.com/.
Additionally, the error page includes information about the incoming web request (GET
and POST data, cookies, CGI headers) and Django settings, helping you identify the
context of the error.
Debugging Aid:
Developers accustomed to debugging with print statements can leverage Django's error
page for debugging purposes by inserting an assert False statement at any point in the view
function to trigger the error page and inspect the local variables and program state.
Security Considerations:
It's essential to recognize that the information displayed on Django's error page is sensitive
and should not be exposed on the public internet. Django only displays the error page when
the project is in debug mode, which is automatically activated during development but
should be deactivated in production to prevent potential security risks.
By utilizing Django's error pages effectively, developers can gain valuable insights into
runtime errors, facilitate debugging, and ensure the robustness of their Django applications.
Wildcard patterns, also known as catch-all patterns or wildcard segments, are a useful feature in
Django's URL routing system. They allow you to capture any part of a URL and pass it as a
parameter to a view function. Here's how wildcard patterns work in Django's URL configuration:
In Django, URL patterns are defined using regular expressions (regex) in the URLconf
module (urls.py).
Typically, URL patterns match specific URLs and route them to corresponding view
functions.
Wildcard Patterns:
Wildcard patterns allow you to capture variable parts of a URL and pass them as parameters
to view functions.
The most common wildcard pattern in Django's URL routing system is the
(?P<parameter_name>pattern) syntax, where parameter_name is the name of the parameter
and pattern is a regex pattern that matches the parameter value.
This syntax captures the matched part of the URL and passes it as an argument to the
associated view function.
Usage Example:
Let's say you want to create a dynamic URL pattern for displaying details of a specific
item. Instead of creating separate URL patterns for each item, you can use a wildcard
pattern to capture the item's identifier from the URL.
Example:
# urls.py
urlpatterns = [
path('item/<int:item_id>/', views.item_detail),
In this example, <int:item_id> is a wildcard pattern that captures an integer value from the
URL and passes it as the item_id parameter to the item_detail view function.
Parameter Naming:
When using wildcard patterns, it's important to give meaningful names to the captured
parameters to improve code readability.
Parameter names are enclosed in angle brackets (< >) and must be valid Python variable
names.
Wildcard Segment:
Django also supports wildcard segments in URL patterns, denoted by an asterisk (*), which
captures the remainder of the URL as a single parameter.
Wildcard segments are useful for creating catch-all patterns to handle dynamic routes.
# urls.py
urlpatterns = [
path('blog/<slug:category>/', views.blog_category),
path('blog/<slug:category>/<path:remainder>/', views.blog_post),
In this example, <path:remainder> is a wildcard segment that captures the remaining part
of the URL as a single parameter, allowing for dynamic handling of blog posts with
variable URLs.
Wildcard patterns in Django's URL routing system provide flexibility and enable the creation of
dynamic and expressive URL patterns, making it easier to build robust and scalable web
applications
Module-01
Web Framework
Django: High-level Python web framework for rapid development. Features include an ORM,
URL routing, template engine, admin interface, and strong security. Best for large, database-
driven applications.
Django is a high-level Python web framework that encourages rapid development and clean,
pragmatic design. It follows the model-template-view (MTV) architectural pattern, which is
similar to the model-view-controller (MVC) pattern used in other frameworks.
1. ORM (Object-Relational Mapping): Django provides a powerful ORM that allows you
to interact with databases using Python code instead of raw SQL.
2. URL Routing: It uses a URL configuration file to map URLs to views, making it easy to
create clean, SEO-friendly URLs.
3. Template Engine: Django has a template language that allows you to separate the design
from Python code.
4. Forms: It offers a form framework that handles rendering forms, validating user input,
and processing submitted data.
5. Authentication and Authorization: Django comes with a robust user authentication
system out of the box.
6. Admin Interface: It automatically generates an admin interface for your models, which
is great for managing your site's content.
7. Security Features: Django provides protection against common web vulnerabilities like
XSS, CSRF, SQL injection, etc.
The MVC design pattern is a software architecture pattern that separates an application
into three main components: Model, View, and Controller, making it easier to manage
and maintain the codebase.
It also allows for the reusability of components and promotes a more modular approach
to software development.
The Model View Controller (MVC) design pattern specifies that an application consists
of a data model, presentation information, and control information. The pattern requires
that each of these be separated into different objects.
How the MVC pattern works in general and how it can be related to Django in scope.
The MVC pattern is a software architecture pattern that separates data presentation from
the logic of handling user interactions (in other words, saves you stress:), it has been around as a
concept for a while, and has invariably seen an exponential growth in use since its inception. It has
also been described as one of the best ways to create client-server applications, all of the best
frameworks for web are all built around the MVC concept.
Model: This handles your data representation, it serves as an interface to the data stored in the
database itself, and also allows you to interact with your data without having to get perturbed with
all the complexities of the underlying database.
View: As the name implies, it represents what you see while on your browser for a web application
or In the UI for a desktop application.
Controller:
data i.e. it uses programmed logic to figure out what is pulled from the database through the model
and passed to the view, also gets information from the user through the view and implements the
given logic by either changing the view or updating the data via the model, To make it more
simpler, see it as the engine room.
Now that we understand the general concept of the MVC, understanding how it is implemented in
different frameworks can be another task as some frameworks (Django inclusive) like to
implement this same functionality in another way making it a bit difficult understanding what
actually happens at each layer.
implementation, the framework considers handling the Controller part of the MVC itself and
letting most of the good stuff happen in the Model-Template-View, this is why Django is mostly
referred to as the MTV framework.
Defines the database model for a book using Django's models. Model class.
Contains a Book class with two fields: name (CharField) and pub_date (DateField).
Represents the data layer of the application
class Book(models.Model):
name = models.CharField(max_length=50)
pub_date = models.DateField()
def latest_books(request):
book_list = Book.objects.order_by('-pub_date')[:10]
urlpatterns = patterns('',
(r'^latest/$', views.latest_books),
<html>
<head>
<title>Books</title>
</head>
<body>
<h1>Books</h1>
<ul>
{% endfor %}
</ul>
</body>
</html>
The components are loosely coupled, allowing for independent changes and enhancing
maintainability and scalability of the application.
Django Evolution
1. Origins: Django was created by Adrian Holovaty and Simon Willison in the fall of 2003.
They were web programmers at the Lawrence Journal-World newspaper in Lawrence,
Kansas, USA.
3. Organic Growth: Django grew organically from the real-world needs of the development
team. They initially built applications from scratch but soon realized the need for a
framework to streamline their process.
4. Framework Creation: Following the typical path of many web developers, the team
started refactoring their code to share common functionalities across applications. This led
to the creation of a framework.
5. Open-Source Release: In the summer of 2005, after developing the framework to a usable
state, the team, including Jacob Kaplan-Moss, decided to release it as open source software
in July 2005.
6. Name Origin: The framework was named Django after the jazz guitarist Django
Reinhardt.
8. Sweet Spot: Django's origins in a news environment influenced its design, making it
particularly well-suited for content sites with dynamic, database-driven information.
However, it's effective for building a wide range of dynamic websites.
1.8 LTS 1 Apr 2015 Native support for multiple template engines.Supported until
at least April 2018
1.9 1 Dec 2015 Automatic password validation. New styling for admin
interface.
1.10 1 Aug 2016 Full text search for PostgreSQL. New-style middleware.
1.11 LTS 1.11 LTS Last version to support Python 2.7.Supported until at least April
2020
2.0 Dec 2017 First Python 3-only release, Simplified URL routing syntax,
Mobile friendly admin.
In Django, views are Python functions that handle web requests and return web responses.
The views.py file is a convention for organizing view functions within a Django project.
To create a view, you define a Python function that takes an HttpRequest object as its first
parameter and returns an HttpResponse object.
In the provided example, the hello view function simply returns an HttpResponse object
with the text "Hello world".
# views.py
def hello(request):
Explanation:
In the URLconf, you import the view functions from views.py and map them to specific
URLs using regular expressions.
Each URL pattern is defined as a tuple containing a regular expression pattern and the
corresponding view function.
In the provided example, the URL pattern r'^hello/$' maps to the hello view function,
indicating that the view should be invoked when the URL /hello/ is requested.
# urls.py
urlpatterns = patterns('',
(r'^hello/$', views.hello),
Explanation:
Import necessary modules and the hello view function from views.py.
Define the urlpatterns variable, which is a mapping between URLs and the view functions.
Map the URL /hello/ to the hello view function. When a user visits this URL, Django will
call the hello function.
This setup tells Django to display "Hello world" when a user navigates to the /hello/ URL in the
browser.
Request Handling:
When a user makes a request to the Django server, Django's URL resolver examines the
requested URL and determines which view function to call based on the URLconf.
The view function receives an HttpRequest object as its first parameter, which contains
metadata about the request (e.g., headers, user agent, request method).
Although the hello view function doesn't utilize the HttpRequest object in this example, it's
a standard parameter for all view functions in Django.
Response Generation:
URL Mapping:
URL patterns defined in the URLconf serve as a mapping between URLs and view
functions.
Django uses regular expressions to match incoming URLs to patterns defined in the
URLconf.
When a matching URL is found, Django calls the corresponding view function to handle
the request and generate the response.
In a dynamic web application, URLs often contain parameters that influence the output of the page.
To demonstrate this, let's create a view in Django that displays the current date and time offset by
a certain number of hours. Instead of creating separate views for each hour offset, which would
clutter the URLconf, we can use a single view with a parameter in the URL to specify the hour
offset dynamically.
View Function:
We'll create a single view function named offset_datetime, which takes an hour offset as a
parameter and returns the current date and time offset by that number of hours.
# views.py
try:
offset_hours = int(offset)
dt = datetime.now() + timedelta(hours=offset_hours)
except ValueError:
2. URL Configuration:
We'll define a dynamic URL pattern with a parameter to specify the hour offset.
# urls.py
urlpatterns = patterns('',
(r'^time/plus/(?P<offset>\d+)/$', views.offset_datetime),
Explanation:
Definition Separation:
In Django, URLconfs are used to map URLs to view functions, specifying which view
function should be called for a given URL pattern.
The URL definitions and the implementation of view functions are kept separate, residing
in two distinct places within the Django project.
Interchangeability:
Loose coupling ensures that changes made to one component have minimal impact on
others.
If two pieces of code are loosely coupled, modifications to one piece won't require changes
to the other, promoting flexibility and maintainability.
Flexibility in Changes:
With Django's URLconfs, you can modify URL patterns without affecting the view
functions they map to, and vice versa.
For example, changing the URL pattern for a view (e.g., moving from /time/ to /current-
time/) can be accomplished without altering the view function itself.
Similarly, modifications to the view function's logic can be made independently of URL
changes.
Scalability:
Loose coupling enables easy scaling and extension of functionality within a Django project.
Adding new URLs or modifying existing ones can be done without disrupting other parts
of the application.
For instance, exposing a view function at multiple URLs can be achieved by editing the
URLconf without touching the view code.
Maintainability:
Separating URL definitions and view implementations promotes code clarity and makes it
easier to understand and maintain the project.
Developers can focus on specific tasks (e.g., URL routing or view logic) without needing
extensive knowledge of other components.
By leveraging loose coupling, Django enables developers to build web applications that are
flexible, modular, and easy to maintain.
This approach aligns with Django's philosophy of promoting rapid development and scalability
while ensuring code robustness and maintainability.
Errors in Django
When you deliberately introduce a Python error into your Django project, such as commenting out
critical lines of code, Django's error handling mechanisms come into play. Let's delve into how
Django's error pages help you debug and understand the issue:
Error Introduction:
By commenting out crucial lines of code in a view function, you intentionally introduce a
Python error into your Django project.
When you navigate to a URL that triggers the error, Django displays a detailed error page
with significant information about the exception.
At the top of the error page, Django presents key information about the exception,
including the type of exception, parameters, file name, and line number where the
exception occurred.
Additionally, Django provides the full Python traceback for the exception, displaying each
level of the stack trace along with the corresponding file, function/method name, and line
number.
Interactive Traceback:
Django's error page offers an interactive traceback, allowing you to click on any line of
source code to view several lines before and after the erroneous line, providing context for
better understanding.
You can also click on "Local vars" under any frame in the stack to view a table of all local
variables and their values at the exact point where the exception was raised, aiding in
debugging.
Django offers options to easily share the traceback with others for technical support. You
can switch to a copy-and-paste view or share the traceback on a public website like
http://www.dpaste.com/.
Additionally, the error page includes information about the incoming web request (GET
and POST data, cookies, CGI headers) and Django settings, helping you identify the
context of the error.
Debugging Aid:
Developers accustomed to debugging with print statements can leverage Django's error
page for debugging purposes by inserting an assert False statement at any point in the view
function to trigger the error page and inspect the local variables and program state.
Security Considerations:
It's essential to recognize that the information displayed on Django's error page is sensitive
and should not be exposed on the public internet. Django only displays the error page when
the project is in debug mode, which is automatically activated during development but
should be deactivated in production to prevent potential security risks.
By utilizing Django's error pages effectively, developers can gain valuable insights into
runtime errors, facilitate debugging, and ensure the robustness of their Django applications.
Wildcard patterns, also known as catch-all patterns or wildcard segments, are a useful feature in
Django's URL routing system. They allow you to capture any part of a URL and pass it as a
parameter to a view function. Here's how wildcard patterns work in Django's URL configuration:
In Django, URL patterns are defined using regular expressions (regex) in the URLconf
module (urls.py).
Typically, URL patterns match specific URLs and route them to corresponding view
functions.
Wildcard Patterns:
Wildcard patterns allow you to capture variable parts of a URL and pass them as parameters
to view functions.
The most common wildcard pattern in Django's URL routing system is the
(?P<parameter_name>pattern) syntax, where parameter_name is the name of the parameter
and pattern is a regex pattern that matches the parameter value.
This syntax captures the matched part of the URL and passes it as an argument to the
associated view function.
Usage Example:
Let's say you want to create a dynamic URL pattern for displaying details of a specific
item. Instead of creating separate URL patterns for each item, you can use a wildcard
pattern to capture the item's identifier from the URL.
Example:
# urls.py
urlpatterns = [
path('item/<int:item_id>/', views.item_detail),
In this example, <int:item_id> is a wildcard pattern that captures an integer value from the
URL and passes it as the item_id parameter to the item_detail view function.
Parameter Naming:
When using wildcard patterns, it's important to give meaningful names to the captured
parameters to improve code readability.
Parameter names are enclosed in angle brackets (< >) and must be valid Python variable
names.
Wildcard Segment:
Django also supports wildcard segments in URL patterns, denoted by an asterisk (*), which
captures the remainder of the URL as a single parameter.
Wildcard segments are useful for creating catch-all patterns to handle dynamic routes.
# urls.py
urlpatterns = [
path('blog/<slug:category>/', views.blog_category),
path('blog/<slug:category>/<path:remainder>/', views.blog_post),
In this example, <path:remainder> is a wildcard segment that captures the remaining part
of the URL as a single parameter, allowing for dynamic handling of blog posts with
variable URLs.
Wildcard patterns in Django's URL routing system provide flexibility and enable the creation of
dynamic and expressive URL patterns, making it easier to build robust and scalable web
applications
Update settings.py:
Add to INSTALLED_APPS:
'django.contrib.admin'
Ensure 'django.contrib.auth', 'django.contrib.contenttypes', and 'django.contrib.sessions'
are included. Uncomment if previously commented.
Update MIDDLEWARE_CLASSES:
'django.middleware.common.CommonMiddleware'
'django.contrib.sessions.middleware.SessionMiddleware'
'django.contrib.auth.middleware.AuthenticationMiddleware'
Execute python manage.py syncdb to install the necessary database tables for the admin
interface.
If not prompted to create a superuser, run python manage.py createsuperuser to create an
admin account.
Update urls.py:
Logging In:
Visit the admin site and log in with the superuser credentials you created.
manage.py
createsuperuser.
After logging in, you'll see the admin home page listing all data types available for
editing. Initially, it includes only Groups and Users.
Data Management:
Each data type in the admin site has a change list and an edit form.
Change List: Displays all records of a data type, similar to a SELECT * FROM <table>
SQL query.
Edit Form: Allows you to add, change, or delete individual records.
Click the Change link in the Users row to load the change-list page for users.
This page shows all users in the database, with options for filtering, sorting, and
searching.
Filtering: Options are on the right.
Sorting: Click a column header.
Search: Use the search box at the top.
Click a username to see the edit form for that user.
Change user attributes such as first/last names and permissions.
To change a user's password, click the Change Password Form link.
Different field types have different input widgets (e.g., calendar controls for date fields,
checkboxes for Boolean fields).
Add Record: Click Add in the appropriate column on the admin home page to access an
empty edit form for creating a new record.
Delete Record: Click the Delete button at the bottom left of an edit form. Confirm the
deletion on the subsequent page, which may list dependent objects to be deleted as well.
The admin interface validates input automatically. Errors will be displayed if you leave
required fields blank or enter invalid data.
History:
When editing an object, a History link appears in the upper-right corner. This logs every
change made through the admin interface and allows you to review the change history.
To customize a label, use the verbose_name attribute in your model field definitions.
Example:
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField(blank=True, verbose_name='e-mail')
Alternatively, you can pass verbose_name as a positional argument:
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
ModelAdmin classes allow customization of how models are displayed and managed in
the admin interface.
Customizing Change Lists
By default, change lists show the result of the model's __str__ or __unicode__ method.
You can specify which fields to display using the list_display attribute.
class AuthorAdmin(admin.ModelAdmin):
admin.site.register(Author, AuthorAdmin)
class AuthorAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'email')
search_fields = ('first_name', 'last_name')
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date')
list_filter = ('publication_date',)
date_hierarchy = 'publication_date'
ordering = ('-publication_date',)
class BookAdmin(admin.ModelAdmin):
fields = ('title', 'authors', 'publisher', 'publication_date')
Excluding Fields
Exclude fields by omitting them from the fields list:
class BookAdmin(admin.ModelAdmin):
fields = ('title', 'authors', 'publisher')
class BookAdmin(admin.ModelAdmin):
filter_horizontal = ('authors',)
class BookAdmin(admin.ModelAdmin):
filter_vertical = ('authors',)
class BookAdmin(admin.ModelAdmin):
raw_id_fields = ('publisher',)
When and Why to Use the Admin Interface and When Not To
Example Workflow:
1. A reporter meets with a developer to describe the data.
2. The developer creates Django models based on this data and sets up the
admin interface.
3. The reporter reviews the admin site and suggests any changes to the fields.
4. The developer updates the models accordingly.
5. The reporter begins entering data, allowing the developer to focus on
building views and templates.
1. Public Interfaces:
Security and Usability: The admin interface is not designed for public use. It lacks
the security measures and user-friendly design necessary for a public-facing
application.
data queries and manipulations, custom views and tools are more appropriate.
1. Introduction to Forms
Django provides a built-in form handling functionality that simplifies the process
of handling HTML forms in web applications.
Forms in Django are represented by Python classes that map to HTML form fields.
2. Creating a Form
In Django, forms are created by subclassing the forms.Form class or the
forms.ModelForm class (for model-based forms).
Each form field is represented by a class attribute, and the type of the field is
determined by the corresponding Django Field class.
Example:
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
3. Rendering a Form
Forms can be rendered in templates using the {{ form.as_p }} (for paragraph-based
rendering) or {{ form.as_table }} (for table-based rendering) template tags.
Individual form fields can be rendered using {{ form.field_name }}.
7. Form Widgets
Django provides a wide range of built-in form widgets (e.g., TextInput, Textarea,
CheckboxInput, Select, etc.) for rendering form fields.
You can customize the rendering of form fields by specifying the widget argument
when defining the field.
9. CSRF Protection
Django provides built-in protection against Cross-Site Request Forgery (CSRF)
attacks by including a CSRF token in forms.
You need to include the {% csrf_token %} template tag in your form template to
generate the CSRF token.
Create a new file forms.py in your Django app directory, and add the following code
class FeedbackForm(forms.Form):
Create a new file feedback.html in your Django app's templates directory, and add the following
code:
<!DOCTYPE html>
<html>
<head>
<title>Feedback Form</title>
</head>
<body>
<h1>Feedback Form</h1>
<form method="post">
{{ form.non_field_errors }}
<div>
{{ form.name.errors }}
{{ form.name.label_tag }}
{{ form.name }}
</div>
<div>
{{ form.email.errors }}
{{ form.email.label_tag }}
{{ form.email }}
</div>
<div>
{{ form.subject.errors }}
{{ form.subject.label_tag }}
{{ form.subject }}
</div>
<div>
{{ form.message.errors }}
{{ form.message.label_tag }}
{{ form.message }}
</form>
</body>
</html>
Create a new file feedback_success.html in your Django app's templates directory, and add the
following code:
<!DOCTYPE html>
<html>
<head>
<title>Feedback Submitted</title>
</head>
<body>
</body>
</html>
Open your Django app's views.py file and add the following code:
def feedback(request):
if request.method == 'POST':
form = FeedbackForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
email = form.cleaned_data['email']
subject = form.cleaned_data['subject']
message = form.cleaned_data['message']
else:
form = FeedbackForm()
Open your Django app's urls.py file and add the following URL pattern:
urlpatterns = [
Start the Django development server and navigate to http://localhost:8000/feedback/ in your web
browser. You should see the feedback form.
Form submissions
1. Create a Form Class: Define a form class that inherits from forms.Form or
forms.ModelForm. This class defines the fields and validations for your form.
2. Render the Form in a Template: In your template, render the form using the {{ form }}
template tag or individual field tags like {{ form.field_name }}.
3. Check Request Method: In your view function, check if the request method is POST
(form submission) or GET (initial form load).
4. Create Form Instance with Data: If the request method is POST, create a form instance
with the submitted data using form = YourForm(request.POST) or form =
YourModelForm(request.POST).
5. Validate the Form: Call form.is_valid() to validate the form data against the defined fields
and validations.
6. Process Valid Form Data: If the form is valid (form.is_valid() returns True), access the
cleaned data using form.cleaned_data and perform any necessary operations (e.g., save to
the database, send an email, etc.).
8. Redirect or Render Success Page: After successful form processing, it's recommended
to redirect the user to a success page or a different view to prevent duplicate form
submissions on page refresh.
# forms.py
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
# views.py
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
email = form.cleaned_data['email']
message = form.cleaned_data['message']
return redirect('success_url')
else:
form = ContactForm()
<form method="post">
{% csrf_token %}
{{ form.as_p }}
</form>
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
email = forms.EmailField(required=False)
message = forms.CharField(widget=forms.Textarea)
def clean_message(self):
message = self.cleaned_data['message']
num_words = len(message.split())
if num_words < 4:
raise forms.ValidationError("Not enough words!")
return message
This method:
Extracts the message from self.cleaned_data.
Counts the words using split() and len().
Raises a ValidationError if there are fewer than four words.
Returns the cleaned message value.
You can customize the form's appearance using CSS and custom HTML templates
for better control over the presentation.
<html>
<head>
<title>Contact us</title>
</head>
<h1>Contact us</h1>
{% if form.errors %}
</p>
{% endif %}
<div class="field">
{{ form.subject.errors }}
<label for="id_subject">Subject:</label>
{{ form.subject }}
</div>
<div class="field">
{{ form.email.errors }}
{{ form.email }}
</div>
<div class="field">
{{ form.message.errors }}
<label for="id_message">Message:</label>
</div>
</form>
</body>
</html>
This template:
Example
class Contact(models.Model):
subject = models.CharField(max_length=100)
email = models.EmailField(blank=True)
message = models.TextField()
def __str__(self):
return self.subject
Example
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
Example:
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
def clean_message(self):
message = self.cleaned_data['message']
num_words = len(message.split())
if num_words < 4:
return message
Example
def contact_view(request):
form = ContactForm(request.POST)
if form.is_valid():
form.save()
else:
form = ContactForm()
Example
<html>
<head>
<title>Contact Us</title>
</head>
<body>
<h1>Contact Us</h1>
{% if form.errors %}
{% endif %}
<form method="post">
{% csrf_token %}
<div class="field">
{{ form.subject.errors }}
<label for="id_subject">Subject:</label>
{{ form.subject }}
</div>
<div class="field">
{{ form.email.errors }}
{{ form.email }}
</div>
<div class="field">
{{ form.message.errors }}
<label for="id_message">Message:</label>
{{ form.message }}
</div>
</form>
</html>
1. Define the Model: Establish your data structure with a Django model.
2. Create the Model Form: Generate a form using forms.ModelForm based on the model.
3. Add Custom Validation: Optionally include custom validation methods within the form.
4. Use the Form in Views: Implement form handling logic in Django views to process
submissions.
5. Create the Template: Design an HTML template to display and manage the form
interface.
URLConf Ticks
Example:
Example
from django.conf.urls.defaults import *
from mysite import views
urlpatterns = patterns('',
(r'^hello/$', views.hello),
(r'^time/$', views.current_datetime),
(r'^time/plus/(d{1,2})/$', views.hours_ahead),
)
Example
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^hello/$', 'mysite.views.hello'),
(r'^time/$', 'mysite.views.current_datetime'),
(r'^time/plus/(d{1,2})/$', 'mysite.views.hours_ahead'),
)
Advantage: No need to import view functions; Django handles imports
automatically.
Example:
urlpatterns = patterns('mysite.views',
(r'^hello/$', 'hello'),
(r'^time/$', 'current_datetime'),
(r'^time/plus/(d{1,2})/$', 'hours_ahead'),
Flexibility:
Both approaches are valid and can be mixed within the same URLconf depending
on personal coding style and project needs.
Basic Usage
Important Considerations
Main URLconf:
urlpatterns = patterns('',
(r'^weblog/', include('mysite.blog.urls')),
(r'^photos/', include('mysite.photos.urls')),
(r'^about/$', 'mysite.views.about'),
1. Request: /weblog/2007/
First URLconf: r'^weblog/' matches.
Action: Strips weblog/.
Remaining URL: 2007/.
Result: Matches r'^(\d\d\d\d)/$' in mysite.blog.urls.
3. Request: /about/
First URLconf: Matches r'^about/$'.
Result: Maps to mysite.views.about view.
Mixing Patterns
Flexibility: You can mix include() patterns with non-include() patterns within the same
URLconf.
Basic Concept
Generic Views: Django provides built-in views that can handle common patterns,
reducing the need to write repetitive view code.
Configuration: Use configuration dictionaries in URLconf files, passing them as the third
member of the URLconf tuple.
1. Simple URLconf
urlpatterns = patterns('',
(r'^about/$', direct_to_template, {'template': 'about.html'})
)
Explanation: direct_to_template is used to render about.html without additional view
code.
urlpatterns = patterns('',
(r'^about/$', direct_to_template, {'template': 'about.html'}),
(r'^about/(\w+)/$', about_pages),
)
Explanation:
2. Advantages:
Generic views can be called within custom views, returning HttpResponse objects
directly.
Custom error handling, like catching TemplateDoesNotExist, can be implemented for
more robust applications.
Purpose: Simplifies creating views that display lists and details of database objects.
Benefits: Reduces repetitive code, leverages built-in Django functionality for common
tasks.
1. Model Definition:
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
def __unicode__(self):
return self.name
class Meta:
ordering = ['name']
publisher_info = {
'queryset': Publisher.objects.all(),
'template_name': 'publisher_list_page.html',
}
urlpatterns = patterns('',
(r'^publishers/$', list_detail.object_list, publisher_info)
)
4. Template Example:
{% extends "base.html" %}
{% block content %}
<h2>Publishers</h2>
<ul>
{% for publisher in object_list %}
<li>{{ publisher.name }}</li>
{% endfor %}
</ul>
{% endblock %}
Context Variable: object_list contains all publisher objects.
Info Dictionary: The dictionary passed to the generic view can be customized to
include additional options.
Template Context: Additional context variables can be passed to the template by
modifying the dictionary.
Generic View Options: Appendix C of the Django documentation provides
detailed information on all available options for generic views.
1. Ease of Use: Generic views simplify the creation of common views for database objects.
2. Flexibility: Options in the info dictionary allow for extensive customization without
writing additional view code.
3. Template Inference: Django can infer template names, but explicit specification is
possible for better control.
4. Reusability: Generic views promote code reusability and maintainability across projects.
Using generic views can significantly speed up development in Django, but there are
times when they need to be extended to handle more complex use cases.
Here are some common patterns for extending generic views:
Instead of using the default variable name object_list, use a more descriptive name like
publisher_list. This can be achieved with the template_object_name argument.
publisher_info = {
'queryset': Publisher.objects.all(),
'template_name': 'publisher_list_page.html',
'template_object_name': 'publisher',
urlpatterns = patterns('',
{% extends "base.html" %}
{% block content %}
<h2>Publishers</h2>
<ul>
{% endfor %}
</ul>
{% endblock %}.
You can add extra context to the template by using the extra_context argument. Use a
callable to ensure the context is evaluated each time the view is called.
publisher_info = {
'queryset': Publisher.objects.all(),
'template_object_name': 'publisher',
'extra_context': {'book_list': Book.objects.all}
}
Example
apress_books = {
'template_name': 'books/apress_list.html'
urlpatterns = patterns('',
Example
return list_detail.object_list(
request,
queryset=Book.objects.filter(publisher=publisher),
template_name='books/books_by_publisher.html',
template_object_name='book',
extra_context={'publisher': publisher}
urlpatterns = patterns('',
(r'^books/(\w+)/$', books_by_publisher),
import datetime
response = list_detail.object_detail(
request,
queryset=Author.objects.all(),
object_id=author_id,
now = datetime.datetime.now()
Author.objects.filter(id=author_id).update(last_accessed=now)
return response
urlpatterns = patterns('',
# ...
(r'^authors/(?P<author_id>\d+)/$', author_detail),
# ...
def author_list_plaintext(request):
response = list_detail.object_list(
request,
queryset=Author.objects.all(),
mimetype='text/plain',
template_name='books/author_list.txt'
return response
1. Structure:
MIME types have a format: type/subtype.
Example: image/jpeg for JPEG images.
Text
HTML: text/html
Example: An .html file for web pages.
CSS: text/css
Example: A .css file for styling web pages.
Image
JPEG: image/jpeg
Example: A .jpg or .jpeg file.
PNG: image/png
Example: A .png file.
GIF: image/gif
Example: A .gif file for simple animations.
Audio
MP3: audio/mpeg
Example: An .mp3 music file.
WAV: audio/wav
Example: A .wav sound file.
Application
JSON: application/json
Example: A .json file for structured data.
PDF: application/pdf
Example: A .pdf document.
ZIP: application/zip
Example: A .zip compressed file.
Word Document: application/vnd.openxmlformats-
officedocument.wordprocessingml.document
Example: A .docx file created by Microsoft Word.
3. Usage in HTTP:
MIME types are specified in HTTP headers to indicate the type of content.
Example
HTTP/1.1 200 OK
This header tells the client that the content is an HTML document.
6. Registration:
Official MIME types are registered with IANA (Internet Assigned Numbers
Authority).
1. CSV Format:
Simple data format for table rows, separated by commas.
Example
Year, Unruly Airline Passengers
1995,146
1996,184
1997,235
1998,200
1999,226
2000,251
2001,299
2002,273
2003,281
2004,304
2005,203
2006,134
2007,147
UNRULY_PASSENGERS = [146, 184, 235, 200, 226, 251, 299, 273, 281, 304,
203, 134, 147]
def unruly_passengers_csv(request):
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="unruly.csv"'
writer = csv.writer(response)
writer.writerow(['Year', 'Unruly Airline Passengers'])
for year, num in zip(range(1995, 2008), UNRULY_PASSENGERS):
writer.writerow([year, num])
return response
1. PDF Format:
PDF (Portable Document Format) is used for printable documents with precise
formatting.
1. Initialization:
Add a URLconf to activate syndication feeds.
This directs all URLs starting with /feeds/ to the RSS framework.
Customize the URL prefix (feeds/) as needed.
2. URL Configuration:
Use feed_dict to map feed slugs to Feed classes:
from django.conf.urls.defaults import *
from mysite.feeds import LatestEntries, LatestEntriesByCategory
feeds = {
'latest': LatestEntries,
'categories': LatestEntriesByCategory,
}
urlpatterns = patterns('',
# ...
(r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds}),
# ...
)
Example:
class LatestEntries(Feed):
title = "Latest Blog Entries"
link = "/latest/"
description = "Updates on the latest blog entries."
def items(self):
return Entry.objects.order_by('-pub_date')[:5]
A sitemap is an XML file that helps search engines index your site.
Tells search engines how frequently pages change and their importance.
Example
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://www.djangoproject.com/documentation/</loc>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
</url>
<url>
<loc>http://www.djangoproject.com/documentation/0_90/</loc>
<changefreq>never</changefreq>
<priority>0.1</priority>
</url>
</urlset>
1. Installation:
Add 'django.contrib.sitemaps' to INSTALLED_APPS.
Ensure 'django.template.loaders.app_directories.load_template_source' is in
TEMPLATE_LOADERS.
Install the sites framework.
2. Initialization:
Add this line to URLconf to activate sitemap generation
(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps':
sitemaps})
The dot in sitemap.xml is escaped with a backslash.
class BlogSitemap(Sitemap):
changefreq = "never"
priority = 0.5
def items(self):
return Entry.objects.filter(is_draft=False)
sitemaps = {
'blog': BlogSitemap,
}
urlpatterns = patterns('',
(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps':
sitemaps}),
)
4. Sitemap Class:
Subclass django.contrib.sitemaps.Sitemap.
Define methods and attributes such as items, lastmod, changefreq, priority.
class BlogSitemap(Sitemap):
changefreq = "never"
priority = 0.5
def items(self):
return Entry.objects.filter(is_draft=False)
return obj.pub_date
6. Convenience Classes:
FlatPageSitemap: For flatpages defined for the current site.
GenericSitemap: Works with generic views.
info_dict = {
'queryset': Entry.objects.all(),
'date_field': 'pub_date',
}
sitemaps = {
'flatpages': FlatPageSitemap,
'blog': GenericSitemap(info_dict, priority=0.6),
}
urlpatterns = patterns('',
(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}),
)
class Entry(models.Model):
# ...
def save(self, *args, **kwargs):
super(Entry, self).save(*args, **kwargs)
try:
ping_google()
except Exception:
pass
Command-line:
python manage.py ping_google /sitemap.xml
Introduction to Cookies:
Example:
Browser requests a page from Google:
GET / HTTP/1.1
Host: google.com
Reading Cookies:
Use the COOKIES attribute of HttpRequest to read cookies.
def show_color(request):
if "favorite_color" in request.COOKIES:
return HttpResponse("Your favorite color is %s" %
request.COOKIES["favorite_color"])
else:
return HttpResponse("You don't have a favorite color.")
Writing Cookies:
Use the set_cookie() method of HttpResponse to set cookies.
def set_color(request):
if "favorite_color" in request.GET:
response = HttpResponse("Your favorite color is now %s" %
request.GET["favorite_color"])
response.set_cookie("favorite_color", request.GET["favorite_color"])
return response
else:
return HttpResponse("You didn't give a favorite color.")
Security Concerns:
Cookies sent over HTTP are vulnerable to snooping attacks.
Never store sensitive information in cookies.
Man-in-the-Middle Attacks: Attackers can intercept and use cookies to impersonate
users.
Tampering:
Browsers allow users to edit cookies, making it risky to store important state
information in cookies.
Example of a security mistake:
# Storing something like IsLoggedIn=1 in a cookie can be easily tampered with.
Django's session framework addresses the limitations and potential security issues of using
cookies directly by providing a way to store and retrieve arbitrary data on a per-site visitor
basis.
The session data is stored server-side, with only a hashed session ID sent to the client,
mitigating many common cookie-related issues.
Enabling Sessions
Middleware and Installed Apps:
Ensure SessionMiddleware is included in your MIDDLEWARE_CLASSES
MIDDLEWARE_CLASSES = [
...
'django.contrib.sessions.middleware.SessionMiddleware',
...
]
Ensure django.contrib.sessions is in your INSTALLED_APPS.
INSTALLED_APPS = [
...
'django.contrib.sessions',
...
]
1. Example Views
Preventing Multiple Comments:
def post_comment(request):
if request.method != 'POST':
raise Http404('Only POSTs are allowed')
if 'comment' not in request.POST:
raise Http404('Comment not submitted')
if request.session.get('has_commented', False):
return HttpResponse("You've already commented.")
c = comments.Comment(comment=request.POST['comment'])
c.save()
request.session['has_commented'] = True
return HttpResponse('Thanks for your comment!')
3. Logging Out:
def logout(request):
try:
del request.session['member_id']
except KeyError:
pass
return HttpResponse("You're logged out.")
Testing Cookie Acceptance
To test if a browser accepts cookies:
Set the test cookie
request.session.set_test_cookie()
s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead')
session_data = s.get_decoded()
By default, Django saves the session to the database only if it has been modified:
request.session['foo'] = {} # Modified