0% found this document useful (0 votes)
13 views112 pages

Module 3 - FSD

This document provides an overview of Django's admin interface and model forms, detailing how to activate and customize the admin site for managing site content. It covers essential topics such as logging in, managing users, adding models, customizing field labels, and implementing various features like search bars and filters. The document emphasizes the importance of the admin interface for non-technical users and developers in managing data efficiently.

Uploaded by

chan3024cs
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views112 pages

Module 3 - FSD

This document provides an overview of Django's admin interface and model forms, detailing how to activate and customize the admin site for managing site content. It covers essential topics such as logging in, managing users, adding models, customizing field labels, and implementing various features like search bars and filters. The document emphasizes the importance of the admin interface for non-technical users and developers in managing data efficiently.

Uploaded by

chan3024cs
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 112

Full Stack Development

Module 3 : Django Admin Interfaces


and Model Forms
Module 3 : Django Admin Interfaces and Model Forms

• Topics:
1. Activating Admin Interfaces
2. Using Admin Interfaces
3. Customizing Admin Interfaces
4. Reasons to Use Admin Interfaces
5. Form Processing, Creating feedback forms
6. Form Submission, Custom Validation, Creating model forms
7. UrlConf Ticks, Including other URLConfs
Introduction
• For a certain class of Web sites, an admin interface is an essential part of the
infrastructure. This is a Web-based interface, limited to trusted site
administrators, that enables the adding, editing, and deletion of site content.

• This chapter is about Django’s automatic admin interface. The feature works by
reading metadata in your model to provide a powerful and production-ready
interface that site administrators can start using immediately.
The django.contrib Packages
• django.contrib is a package that contains a collection of Django’s built-in
applications and utilities, which are often referred to as "contrib" apps.
• These apps provide commonly needed features and functionalities that you can
easily integrate into your Django projects. One of the most notable contrib apps is
the Django admin interface.
• The django.contrib package includes several modules, but the most relevant one
for the admin interface is django.contrib.admin
Activating the Admin Interface
The Django admin site is entirely optional, because only certain types of sites need this
functionality. That means you’ll need to take a few steps to activate it in your project.
First, make a few changes to your settings file:
1. Add 'django.contrib.admin' to the INSTALLED_APPS setting. (The order of INSTALLED_
APPS doesn’t matter, but we like to keep things alphabetical so it’s easy for a human to
read.)
2. Make sure INSTALLED_APPS contains 'django.contrib.auth','django.contrib.
contenttypes', and 'django.contrib.sessions'. The Django admin site requires these three
packages.
3. Make sure MIDDLEWARE_CLASSES contains 'django.middleware.common.
CommonMiddleware’, 'django.contrib.sessions.middleware.SessionMiddleware', and
'django.contrib. auth.middleware.AuthenticationMiddleware’.
Activating the Admin Interface
Second, run python manage.py syncdb. This step will install the extra database tables that
the admin interface uses.

Now in recent versions of Django, This command has been removed . We have to use
python manage.py makemigrations and python manage.py migrate commands instead.

Third, add the admin site to your URLconf (in urls.py, remember). By default, the urls.py
generated by django-admin.py startproject contains commented-out code for the Django
admin, and all you have to do is uncomment it.
But in the recent versions of Django, these lines are already uncommented.
Next, Create username and password to login to the admin site of Django using python
manage.py createsuperuser command
Activating the Admin Interface

• Now we can see the Django admin site in action. Just run the development server
(python manage.py runserver) and visit http://127.0.0.1:8000/admin/ in your
Web browser. The admin page will be displayed.

• Add the credentials(username and password) created using python manage.py


createsuperuser command.
Activating the Admin Interface
Using the admin Interfaces
Logging In:
• Visit the admin site and log in with the superuser credentials you created.
• If you can't log in, ensure you’ve created a superuser by running python manage.py
createsuperuser.
Using the admin Interfaces
Admin Home Page:
• After logging in, you'll see the admin home page listing all data types available for editing.
Initially, it includes only Groups and Users.
• At this point, because we haven’t activated any of our own models yet, the list is sparse: it
includes only Groups and Users, which are the two default admin-editable models.
Using the admin Interfaces
• Each type of data in the Django admin site has a change list and an edit form. Change lists
show you all the available objects in the database.
Using the admin Interfaces
• When you see all the objects displayed, you can click on any of the objects to edit it and
save. The below form is an edit form which allows you to add, change, or delete individual
records.
Using the admin Interfaces
Managing Users:
• 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).
Using the admin Interfaces
Using the admin Interfaces
Add Record: Click Add in the appropriate column on the admin home page to access an
empty edit form for creating a new record.
Using the admin Interfaces
• Delete Record: Click the Delete button at the bottom right of an edit form. Confirm the
deletion on the subsequent page, which may list dependent objects to be deleted as well.
• The below figure mentions about the delete option present in the bottom right corner of
the edit form.
Using the admin Interfaces
• Input Validation:
The admin interface validates input automatically. Errors will be displayed if you leave
required fields blank or enter invalid data.
Using the admin Interfaces
• 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.
When History button is clicked, you can see the changes made to that particular user.
Using the admin Interfaces
• History:
Adding Your Models to the Admin
Site
• There’s one crucial part we haven’t done yet. Let’s add our own models to the admin site
so we can add, change, and delete objects in our custom database tables using this nice
interface.
• Within the app’s directory, there is a file named admin.py which helps to register the
models in the admin site.
• For example :
from django.contrib import admin
from mysite.books.models import Publisher,Author,Book
admin.site.register(Publisher)
admin.site.register(Author)
admin.site.register(Book)
This code tells the Django admin site to offer an interface for each of these models.
Adding Your Models to the Admin
Site
• One feature worth mentioning here is the admin site’s handling of foreign keys and many
to-many relationships, both of which appear in the Book model. As a reminder, here’s
what the Book model looks like:

On the Django admin site’s Add Book page (http://127.0.0.1:8000/admin/books/book/


add/), the publisher (a ForeignKey) is represented by a select box, and the authors field (a
ManyToManyField) is represented by a multiple-select box.
How the Admin Site Works
• When Django loads your URLconf from urls.py at server startup, it executes the admin.
autodiscover() statement that we added as part of activating the admin.
• This function iterates over your INSTALLED_APPS setting and looks for a file called admin.py
in each installed app. If an admin.py exists in a given app, it executes the code in that file.
• In the admin.py, each call to admin.site.register() simply registers the given model with the
admin.
• The admin site will display an edit/change interface for only models that have been
explicitly registered.
Making Fields Optional
• After you play around with the admin site for a while, you’ll probably notice a limitation— the
edit forms require every field to be filled out, whereas in many cases you’d want certain fields
to be optional.
• Let’s say, for example, that we want our Author model’s email field to be optional—that is, a
blank string should be allowed. In the real world, you might not have an e-mail address on file
for every author.
• To specify that the email field is optional, edit the Book model:
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField(blank=True)
This tells Django that a blank value is indeed allowed for authors’ e-mail addresses. By default,
all fields have blank=False, which means blank values are not allowed.
Making Date and Numeric Fields
Optional
• But there’s an exception with database column types that do not accept empty
strings as valid values—such as dates, times, and numbers. If you try to insert an
empty string into a date or an integer column, you’ll likely get a database error.

• In this case, NULL is the only way to specify an empty value. In Django models,
you can specify that NULL is allowed by adding null=True to a field.

• In short, if you want to allow blank values in a date field (e.g., DateField,
TimeField, DateTimeField) or numeric field (e.g., IntegerField, DecimalField,
FloatField), you’ll need to use both null=True and blank=True.
Making Date and Numeric Fields
Optional

class Publisher(models.Model):
name = models.CharField(max_length=100)
Customizing the admin Interfaces
Customizing Field lables
• In the Django admin site, each field’s label is derived from its model field name.
• To customize a label, use the verbose_name attribute in your model field definitions.

The verbose_name attribute is used in recent versions of Django. It allows you to set a
human-readable name for the field, which can be particularly useful for labels in forms and
in the admin interface. So, you can definitely keep using it in your models
Example: To change the Author.email field's label to “e-mail”:
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’)

The above code to be written in models.py of django


Customizing the admin Interfaces
• 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)
email = models.EmailField('e-mail', blank=True)
Customizing the admin Interfaces

Figure : Showing the customized label using verbose


Customizing the admin Interfaces
Custom Model Admin Classes:
• 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.
Customizing the admin Interfaces
Custom Model Admin Classes:
In admin.py file below code is used:
Example:
• To display first_name, last_name, and email for the Author model:
from django.contrib import admin
from mysite.models import Author
class AuthorAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'email’)
admin.site.register(Author, AuthorAdmin)
Customizing the admin Interfaces
• Custom Model Admin Classes:
• Adding a Search Bar
• Add search_fields to your AuthorAdmin:
In admin.py file below code is used:
Example:
class AuthorAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'email’)
search_fields = ('first_name', 'last_name')
Customizing the admin Interfaces
• Adding Date Filters
• Add list_filter to your BookAdmin:
In admin.py file below code is used:
Example:
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date’)
list_filter = ('publication_date',)
Customizing the admin Interfaces
• Adding Date Hierarchy
• Add date_hierarchy to BookAdmin:
In admin.py file below code is used:
Example:
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date’)
list_filter = ('publication_date’,)
date_hierarchy = 'publication_date'
Customizing the admin Interfaces
• Changing Default Ordering
• Use ordering to set the default order of records.
In admin.py file below code to be added.
Example:
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'publisher', 'publication_date’)
list_filter = ('publication_date’,)
date_hierarchy = 'publication_date’
ordering = ('-publication_date',)
Customizing the admin Interfaces
• Customizing Edit Forms
• Changing Field Order
• Use the fields option to customize the order of fields:
In admin.py file below code to be added.

Example:

class BookAdmin(admin.ModelAdmin):
fields = ('title', 'authors', 'publisher', 'publication_date')
Customizing the admin Interfaces
• Excluding Fields
• Exclude fields by omitting them from the fields list:
In admin.py file below code to be added.

Example:

class BookAdmin(admin.ModelAdmin):
fields = ('title', 'authors', 'publisher')
Customizing the admin Interfaces
After applying all the options for admin page such as list display, list filter, date
hierarchy, ordering and search fields, you can see the admin page something like this
which is shown below:

Figure : Here displaying about publishers


Customizing the admin Interfaces

Figure : Here displaying about authors


Customizing the admin Interfaces
• Many-to-Many Field Widgets
• Use filter_horizontal for ManyToManyFields:
To be added in admin.py file:

Example:
class BookAdmin(admin.ModelAdmin):
filter_horizontal = ('authors’,)

Alternatively, use filter_vertical:

class BookAdmin(admin.ModelAdmin):
filter_vertical = ('authors',)
Customizing the admin Interfaces
• ForeignKey Field Widgets
• Use raw_id_fields for ForeignKey fields:

To be added in admin.py file:

Example:

class BookAdmin(admin.ModelAdmin):
raw_id_fields = ('publisher',)
Customizing the admin Interfaces
• Another example for manytomany fields which can be executed in Django.
In models.py file:
from django.db import models

class Writer(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField('e-mail', blank=True)

def __str__(self):
return f"{self.first_name} {self.last_name}"
Customizing the admin Interfaces
Continued….

class Publication(models.Model):
title = models.CharField(max_length=30)
publisher = models.CharField(max_length=40)
published_date = models.DateField()
writers = models.ManyToManyField(Writer)
def __str__(self):
return self.title
Customizing the admin Interfaces
In admin.py file:

from django.contrib import admin


from adminpage_custom.models import Writer, Publication
class WriterAdmin(admin.ModelAdmin):
list_display = ('last_name', 'email', 'first_name')
search_fields = ('first_name', 'last_name’)
list_filter = ('first_name', 'last_name')
Customizing the admin Interfaces
In admin.py file continued…..
class PublicationAdmin(admin.ModelAdmin):
fields = ('title', 'publisher', 'published_date', 'writers')
list_display = ('title', 'publisher', 'published_date')
list_filter = ('published_date',)
date_hierarchy = 'published_date'
ordering = ('-published_date',)
filter_horizontal = ('writers',)
admin.site.register(Writer, WriterAdmin)
admin.site.register(Publication, PublicationAdmin)
Customizing the admin Interfaces
The figure representing the manytomany widgets.
Customizing the admin Interfaces
• When you add raw_id_fields in the code . You will be getting admin page displayed like this:
• If search button is selected in the writers field, you will get a screen which displays list of
writers. From the list, the writers can be selected, but the writers list only contains the raw
IDs instead of the data.
Customizing the admin Interfaces
If you select autocomplete_fields, you can actually select the data instead of raw ids in the writers field. Using + sign in the
writers field, you can add new writers in the list
Reasons to use Admin Interfaces.
• When and Why to Use the Admin Interface
1. For Non-Technical Users:
• Data Entry: The admin interface is designed to enable non-technical users to easily enter
and manage data.
For instance, reporters or content creators can input data without needing to know any
code.
Example Workflow:
2. 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.
Reasons to use Admin Interfaces.
2. Inspecting Data Models:
• Model Validation:
The admin interface is useful for developers to enter dummy data and validate their data
models. This process can help identify modeling errors or inconsistencies early in
development.
3. Managing Acquired Data:
• External Data Sources:
If your application relies on data from external sources (such as user inputs or web crawlers),
the admin interface provides an easy way to inspect and edit this data. It acts as a
convenient tool for data management, complementing your database's command-line utility.
4. Quick and Dirty Data-Management Apps:
•Lightweight Applications:
For personal projects or internal tools that don’t require a polished public interface, the
admin site can serve as a quick solution. For example, it can be used to track expenses or
manage simple data sets, much like a relational spreadsheet.
Reasons to use Admin Interfaces.
• When Not to Use the Admin Interface
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.
2. Sophisticated Sorting and Searching:
• Advanced Data Handling: While the admin site provides basic sorting and searching
capabilities, it’s not built for advanced data manipulation. For complex data queries and
manipulations, custom views and tools are more appropriate.
3. Complex User Interfaces:
• Customization Limits: The admin interface has limitations in terms of customization and
interactivity. If your project requires a highly customized user interface with complex
workflows, a custom-built solution will be more suitable.
Form Processing - Introduction
• A simple Form-Handling Example:
Form Processing - Introduction
• The form displayed in the previous slide is embedded inside the html template which
has some disadvantages listed below:
1) Forms embedded inside the HTML will never help reusability.
2) This does not provide flexibility to the code and makes the html code complex.
When the forms are separated from HTML code we have below advantages:
• Separation of Concerns: By keeping form logic in forms.py, you separate the backend
logic (validation, field types, etc.) from the frontend presentation (HTML). This makes
your code more organized and easier to manage.

• Reusability: Forms defined in forms.py can be reused across multiple views or templates.
For instance, if you need the same form in different parts of your application, you don’t
have to rewrite the form logic repeatedly.
Form Processing - Introduction
• Built-in Validations: Django's forms provide powerful built-in validations and error
handling, which can be implemented in forms.py. This avoids duplicating validation logic in
multiple places.

• Simplifies Template Code: Moving the form logic out of templates and into forms.py keeps
the HTML cleaner and focused on rendering. This is especially helpful when working on
complex forms.

• So, while embedding forms directly in templates might work for simpler use cases,
Django’s structured approach with forms.py is designed to scale with your application's
complexity. It’s all about maintainability and reducing redundant code!
Form Processing
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.
Form Processing
• Example:

from django import forms


class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
Form Processing
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 }}.

4. Handling Form Data


• In the view function, you can access the submitted form data using the request.POST or
request.GET dictionaries.
• To bind the form data to the form instance, use form = MyForm(request.POST) or form =
MyForm(request.GET).
• After binding the data, you can check if the form is valid using form.is_valid().
Form Processing
5. Validating Form Data
• Django provides built-in validation for common field types (e.g., EmailField,
IntegerField, etc.).
• You can define custom validation rules by overriding the clean_fieldname()
method in your form class.
• For complex validation rules, you can override the clean() method in your form
class.
Form Processing
6. Saving Form Data
• For forms not based on models, you can access the cleaned data using
form.cleaned_data and handle it as needed.
• For model-based forms (ModelForm), you can create or update model instances using
form.save().

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.
Form Processing
8. Form Handling in Views
• In the view function, you typically create a form instance, bind the data to it, and
perform validation and data handling.
• After successful form submission, you can redirect the user to another page or render
a success message.

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.
Form Processing
10. Form Inheritance
• Django supports form inheritance, allowing you to create reusable form
components and extend or override them as needed.
• You can use the Meta class to specify form-level attributes, such as labels,
help_texts, and error_messages.
Your First Form class – Creating
Feedback forms
Step 1: Create the Feedback Form Create a new file forms.py in your Django app directory,
and add the following code

from django import forms


class FeedbackForm(forms.Form):
name = forms.CharField(max_length=100, label='Your Name’)
email = forms.EmailField(label='Your Email’)
subject = forms.CharField(max_length=200, label='Subject’)
message = forms.CharField(widget=forms.Textarea, label='Your Feedback')
Your First Form class – Creating
Feedback forms
Let’s hop into the Python interactive interpreter and see what this class can do. The first thing it can
do is display itself as HTML:
from forms.forms import FeedbackForm
f = FeedbackForm()
Print(f)
Output below:
<tr><th><label for="id_subject">Subject:</label></th><td>
<input type="text" name="subject" id="id_subject" /></td></tr>
<tr><th><label for="id_e-mail">E-mail:</label></th><td>
<input type="text" name="e-mail" id="id_e-mail" /></td></tr>
<tr><th><label for="id_message">Message:</label></th><td>
<input type="text" name="message" id="id_message" /></td></tr>
This command will basically display the html format of the Feedback Form
Your First Form class – Creating
Feedback forms
This default output is in the format of an HTML<table>, But there are a few other built-in outputs:
Your First Form class – Creating
Feedback forms
• These previously discussed methods are just shortcuts for the common case of “display
the entire form.” You can also display the HTML for a particular field:
Your First Form class – Creating
Feedback forms
• The second thing Form objects can do is validate data. To do this, create a new Form object
and pass it a dictionary of data that maps field names to data:
f = FeedbackForm({'name': 'abc', 'subject': 'Hello', 'email': '[email protected]', 'message':
'Nice site!'})
Once you’ve associated data with a Form instance, you’ve created a bound Form:
 print(f.is_bound)
Output : False  if no data has been passed to the form.
True  if data has been passed to the form.
print(f.is_valid())
Output : True  it means there are no validation issues
False  it means there are validation issues
If we leave off any of the fields here, then the form is considered as invalid.(for example: leaving
name or subject field).
Your First Form class – Creating Feedback
forms
Here in this below example, The name field is not mentioned but the forms
has name field.
f = FeedbackForm( 'subject': 'Hello’, 'email':'[email protected]', 'message':
'Nice site!'})
So….after executing the above line, the command print(f.is_bound) will return
true. is_bound is returning true because it is not validating the data present in
the form.
But print(f.is_valid()) will show the output as false because all the values for
the given fields are not entered. The valid() used here will actually check for
the valid values in the forms.
Your First Form class – Creating
Feedback forms
• You can drill down to get the field specific errors:
f = FeedbackForm({'subject': 'Hello', 'e-mail': '[email protected]', 'message': 'Nice site!'})
f['name'].errors
['This field is required.’]  This error is displayed if you have not entered any value to the
name field which is a required field in feedback form.
f[‘e-mail'].errors
"Key 'e-mail' not found in 'FeedbackForm'. Choices are: email, message, name, subject." 
This error is displayed because feedback model does not have e-mail field, it only has email
field.
f['message'].errors
[]  It does not give any error because the message field is present in the feedback form and
it is having valid data.
Your First Form class – Creating
Feedback forms
Finally, for Form instances whose data has been found to be valid, a cleaned_data attribute is
available.
This is a dictionary of the submitted data, “cleaned up.” Django’s forms frame work not only
validates data, but cleans it up by converting values to the appropriate Python types, as
shown here:
f = FeedbackForm({'name':'sandhya’, 'subject': 'Hello', 'email': '[email protected]',
'message': 'Nice site!'})
>>> print(f.is_bound)
True
>>> print(f.is_valid())
True
>>> print(f.cleaned_data)
{'name': 'sandhya', 'email': '[email protected]', 'subject': 'Hello', 'message': 'Nice site!'}
Tying form objects into Views
Now that you have some basic knowledge about Form classes, you might see how we can use
this infrastructure to replace some of the cruft in our contact() view. Here’s how we can
rewrite FeedbackForm() to use the forms framework:
from django.shortcuts import render
from .forms import FeedbackForm
def feedback(request):
if request.method == 'POST':
form = FeedbackForm(request.POST)
if form.is_valid():
# Process the feedback data
name = form.cleaned_data['name']
email = form.cleaned_data['email']
subject = form.cleaned_data['subject']
message = form.cleaned_data['message']
return render(request, 'feedback_success.html', {'name': name})
else:
form = FeedbackForm()
return render(request, 'feedback.html', {'form': form})
Tying form objects into Views
FeedbackForm.html

<!DOCTYPE html>
<html>
<head>
<title>Feedback Form</title>
</head>
<body>
<h1>Feedback Form</h1>
<form method="post">
{% csrf_token %}
{{ form.non_field_errors }}
<div>
{{ form.name.errors }}
{{ form.name.label_tag }}
{{ form.name }}
</div>
Tying form objects into Views
FeedbackForm.html continued……
<div>
{{ form.email.errors }} {{ form.message.label_tag }}
{{ form.email.label_tag }} {{ form.message }}
{{ form.email }} </div>
</div> <input type="submit" value="Submit Feedback">
<div> </form>
{{ form.subject.errors }} </body>
{{ form.subject.label_tag }} </html>
{{ form.subject }}
</div>
<div>
{{ form.message.errors }}
Tying form objects into Views
Creating a success template named as : success.html
<!DOCTYPE html>
<html>
<head>
<title>Feedback Submitted</title>
</head>
<body>
<h1>Thank you for your feedback!</h1>
<p>We appreciate your comments, and will review them shortly.</p>
</body>
</html>
Changing How Fields Are Rendered
Probably the first thing you’ll notice when you render this form locally is that the message
field is displayed as an , and it ought to be a <textarea>. We can fix that by setting the field’s
widget:
from django import forms
class FeedbackForm(forms.Form):
name = forms.CharField(max_length=100, label='Your Name')
email = forms.EmailField(label='Your Email')
subject = forms.CharField(max_length=200, label='Subject')
message = forms.CharField(widget=forms.Textarea, label='Your Feedback')

The forms framework separates out the presentation logic for each field into a set of widgets.
Each field type has a default widget, but you can easily override the default or provide a
custom widget of your own. Think of the Field classes as representing validation logic, while
widgets represent presentation logic.
Setting a Maximum Length
• One of the most common validation needs is to check that a field is of a certain size. For
good measure, we should improve our ContactForm to limit the subject to 100 characters. To
do that, just supply a max_length to the CharField, like this:

from django import forms


class FeedbackForm(forms.Form):
name = forms.CharField(max_length=100, label='Your Name')
email = forms.EmailField(label='Your Email')
subject = forms.CharField(max_length=200, label='Subject')
message = forms.CharField(widget=forms.Textarea, label='Your Feedback')
Setting Initial Values
As an improvement to this form, let’s add an initial value for the subject field: "I love your site!" (A little power of suggestion can’t
hurt.) To do this, we can use the initial argument when we create a Form instance:
from django.shortcuts import render
from .forms import FeedbackForm
def feedback(request):
if request.method == 'POST':
form = FeedbackForm(request.POST)
if form.is_valid():
# Process the feedback data
name = form.cleaned_data['name']
email = form.cleaned_data['email']
subject = form.cleaned_data['subject']
message = form.cleaned_data['message']
return render(request, 'feedback_success.html', {'name': name})
else:
form = FeedbackForm(initial={'subject': 'I love your Site!'})
Adding Custom Validation Rules
Imagine we’ve launched our feedback form, and the e-mails have started tumbling in. There’s just one problem: some
of the submitted messages are just one or two words, which isn’t long enough for us to make sense of. We decide to
adopt a new validation policy: four words or more, please.

from django import forms


class FeedbackForm(forms.Form):
name = forms.CharField(max_length=100, label='Your Name')
email = forms.EmailField(label='Your Email')
subject = forms.CharField(max_length=200, label='Subject')
message = forms.CharField(widget=forms.Textarea, label='Your Feedback')
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
Specifying Labels
• By default, the labels on Django’s autogenerated form HTML are created by replacing
under scores with spaces and capitalizing the first letter—so the label for the e-mail field
is "E-mail".
• But, as with Django’s models, we can customize the label for a given field. Just use label,
like so:
from django import forms
class FeedbackForm(forms.Form):
name = forms.CharField(max_length=100, label='Your Name')
email = forms.EmailField(label='Your Email')
subject = forms.CharField(max_length=200, label='Subject')
message = forms.CharField(widget=forms.Textarea, label='Your Feedback')

Output:
• After all the customizations with assigning codes to all the py files. The final step is to run
the server using the python manage.py runserver command. The below is the output:
Output:
• The response page after filling the details and submitting the feedback form is shown
below:
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).
Form Submissions:
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.).
7. Handle Invalid Form Data: If the form is invalid (form.is_valid() returns False), re-render
the form with error messages.
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.
Simple Example Code for form
submissions
# forms.py
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
Simple Example Code for form
submissions
# views.py
from django.shortcuts import render, redirect
from .forms import ContactForm
def contact(request):
if request.method == 'POST’:
form = ContactForm(request.POST)
if form.is_valid():
Simple Example Code for form
submissions
# views.py
# Process the form data
name = form.cleaned_data['name’]
email = form.cleaned_data['email’]
message = form.cleaned_data['message’]
return redirect('success_url’)
else:
form = ContactForm()
return render(request, 'contact.html', {'form': form})
Simple Example Code for form
submissions
<!-- contact.html -->
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
Customizing Form Design
You can customize the form's appearance using CSS and custom HTML templates for better control over the
presentation.
1. CSS for Error Styling:
Define CSS to style error messages for better visibility
<style type="text/css">
ul.errorlist {
margin: 0;
padding: 0;
}
.errorlist li {
background-color: red;
color: white;
display: block;
font-size: 10px;
margin: 0 0 3px;
padding: 4px 5px;
}
</style>
Customizing Form Design
2) Custom HTML Template:
• Instead of using {{ form.as_table }}, manually render the form fields for finer control.
Example:
<html>
<head>
<title>Contact us</title>
</head>
<body>
<h1>Contact us</h1>
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
Customizing Form Design
Example continued…..:
<form action="" method="post">
<div class="field">
{{ form.subject.errors }}
<label for="id_subject">Subject:</label>
{{ form.subject }}
</div>
<div class="field">
{{ form.email.errors }}
<label for="id_email">Your e-mail address:</label>
{{ form.email }}
</div>
Customizing Form Design
Example continued…..:

<div class="field">
{{ form.message.errors }}
<label for="id_message">Message:</label>
{{ form.message }}
</div>
<input type="submit" value="Submit">
</form>
</body>
</html>
Customizing Form Design
3. Advanced Error Handling in Template:
{{ form.message.errors }} displays a <ul class="errorlist"> if errors are present and a blank string if the field is
valid (or the form is unbound). We can also treat form.message.errors as a Boolean or even iterate over it as a
list.
Consider this example:
<div class="field{% if form.message.errors %} errors{% endif %}">
{% if form.message.errors %}
<ul>
{% for error in form.message.errors %} This template:
• Checks for errors and displays them if present.
<li><strong>{{ error }}</strong></li> • Lists individual error messages in an unordered list.
{% endfor %}
</ul>
{% endif %}
<label for="id_message">Message:</label>
{{ form.message }}
Creating Model Forms
The following steps are required for creating model forms:

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.
Example code for creating model
forms:
1. Define the Model in models.py
• Objective: Create a Django model to represent the data structure.
Example:
from django.db import models
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 code for creating model
forms:
2. Create the Model Form in forms.py file
Objective: Use forms.ModelForm to create a form based on the model.
Example
from django import forms
from .models import Contact
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
fields = ['subject', 'email', 'message']
Example code for creating model
forms:
3. Add Custom Validation (Optional) in models.py
Add custom validation logic specific to form fields.
Example:
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
fields = ['subject', 'email', 'message’]
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
Example code for creating model
forms:
4. Use the Form in Views Example
Objective: Handle the form submission and validation within Django views.
Example:
from django.shortcuts import render, redirect
from .forms import ContactForm
def contact_view(request):
if request.method == 'POST’:
form = ContactForm(request.POST)
if form.is_valid():
form.save()
return redirect('success') # Redirect to a success page or another view
else:
form = ContactForm()
return render(request, 'contact_form.html', {'form': form})
Example code for creating model
forms:
Create the Template
Objective: Design an HTML template to render and display the form.
<!DOCTYPE html>
<html>
<head>
<title>Contact Us</title>
</head>
<body>
<h1>Contact Us</h1>
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
Example code for creating model
forms:
Create the Template continued…
Objective: Design an HTML template to render and display the form.

<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 }}
<label for="id_email">Your email address:</label>
{{ form.email }}
</div>
Example code for creating model
forms:
Create the Template continued…
Objective: Design an HTML template to render and display the form.

<div class="field">
{{ form.message.errors }}
<label for="id_message">Message:</label>
{{ form.message }}
</div>
<input type="submit" value="Submit">
</form>
</body>
</html>
URLConf Ticks
• There’s nothing “special” about URLconfs—like anything else in Django, they’re just Python
code. You can take advantage of this in several ways, as described in the sections that follow.
Streamlining Function Imports
from django.conf.urls.defaults import *
from mysite.views import hello, current_datetime
urlpatterns = patterns(‘ ’,
(r'^hello/$', hello),
(r'^time/$', current_datetime),
)
But as a Django application grows in complexity, its URLconf grows, too, and keeping those
imports can be tedious to manage. It’s possible to avoid that tedium by importing the views
module itself.
Note: from django.conf.urls.defaults import * is outdated as of Django 1.6 and was removed in
later versions. Instead, you should use from django.conf.urls import url or from django.urls import
path in modern Django projects.
URLConf Ticks
The updated code for the recent versions of Django:
from django.urls import path
from mysite.views import hello, current_datetime
urlpatterns = [
path('hello/', hello, name='hello'),
path('time/', current_datetime, name='current_datetime'),
]
.
[OR]
from django.urls import re_path
from mysite.views import hello, current_datetime, hours_ahead
urlpatterns = [
re_path(r'^hello/$', hello, name='hello'),
re_path(r'^time/$', current_datetime, name='current_datetime'),
]
Advantage: Simplifies imports, but still requires module import.
URLConf Ticks
Importing the Views Module:
Example:
from django.conf.urls.defaults import *
from mysite import views
urlpatterns = patterns(‘’,
(r'^hello/$', views.hello),
(r'^time/$', views.current_datetime),
)
Advantage: Simplifies imports, but still requires module import.
URLConf Ticks

The updated code for the recent versions of Django


from django.urls import path, re_path
from mysite import views

urlpatterns = [
path('hello/', views.hello, name='hello'),
path('time/', views.current_datetime, name='current_datetime'),
]
URLConf Ticks
Using Strings to Specify View Functions
Django offers another way of specifying the view function for a particular pattern in the URLconf:
you can pass a string containing the module name and function name rather than the function
object itself.
Example
from django.conf.urls.defaults import *
urlpatterns = patterns(‘’,
(r'^hello/$', 'mysite.views.hello’),
(r'^time/$', 'mysite.views.current_datetime’),
)
Advantage: No need to import view functions; Django handles imports automatically.
Note: from django.conf.urls.defaults import * is outdated as of Django 1.6 and was removed in
later versions. Instead, you should use from django.conf.urls import url or from django.urls
import path in modern Django projects.
URLConf Ticks
The code in the recent version of Django:
from django.urls import path
urlpatterns = [
path('hello/', 'mysite.views.hello', name='hello'),
path('time/', 'mysite.views.current_datetime’, name='current_datetime’),
]
URLConf Ticks
• Factoring Out a Common View Prefix:

Example:
from django.conf.urls.defaults import *
urlpatterns = patterns('mysite.views’,
(r'^hello/$', 'hello’),
(r'^time/$', 'current_datetime’),
)

Advantage: Reduces redundancy by factoring out common prefixes.


URLConf Ticks
The code in the recent version of Django:
from django.urls import path
from mysite import views

urlpatterns = [
path('hello/', views.hello, name='hello'),
path('time/', views.current_datetime, name='current_datetime'),
]
Including other URLconfs
If you intend your code to be used on multiple Django-based sites, you should consider
arranging your URLconfs in such a way that allows for “including.”
Purpose and Benefit
1. Purpose: Allows for modular organization of URL patterns by "including" URLconf modules
from different parts of the project.
2. Benefit: Enhances reusability and maintainability across multiple Django-based sites.
from django.conf.urls.defaults import *
urlpatterns = patterns(‘’,
(r'^weblog/', include('blog.urls')),
(r'^photos/', include(‘photos.urls’)),
)
Note: from django.conf.urls.defaults import * is outdated as of Django 1.6 and was removed
in later versions.
Including other URLconfs
The code in the recent versions of Django:
from django.urls import path, include

urlpatterns = [
path('weblog/', include('blog.urls')),
path('photos/', include('photos.urls’)),
]
Including other URLconfs
Continuing this example, here’s the URLconf mysite.blog.urls:
from django.conf.urls.defaults import *
urlpatterns = patterns(‘’,
(r'^(\d\d\d\d)/$', 'mysite.blog.views.year_detail’),
(r'^(\d\d\d\d)/(\d\d)/$', 'mysite.blog.views.month_detail’),
)
Including other URLconfs
Sample Request Handling
1. Request: /weblog/2007/
2. • First URLconf: r'^weblog/' matches.
3. • Action: Strips weblog/.
4. • Remaining URL: 2007/.
5. • Result: Matches r'^(\d\d\d\d)/$' in mysite.blog.urls.
Including other URLconfs
2. Request: /weblog//2007/ (with two slashes)
• First URLconf: r'^weblog/' matches.
• Action: Strips weblog/.
• Remaining URL: /2007/ (with leading slash).
• Result: Does not match any patterns in mysite.blog.urls.
Including other URLconfs
With these two URLconfs, here’s how a few sample requests would be
handled:
• /weblog/2007/: In the first URLconf, the pattern 'weblog/' matches. Because
it is an include(), Django strips all the matching text, which is 'weblog/' in this
case. The remaining part of the URL is 2007/, which matches the first line in
the mysite.blog. urls URLconf.

• /weblog//2007/ (with two slashes): In the first URLconf, the pattern


'weblog/' matches. Because it is an include(), Django strips all the matching
text, which is 'weblog/' in this case. The remaining part of the URL is /2007/
(with a leading slash), which does not match any of the lines in the
mysite.blog.urls URLconf.

You might also like