Sign In Start Free Trial
Account

Add to playlist

Create a Playlist

Modal Close icon
You need to login to use this feature.
  • Django 3 Web Development Cookbook
  • Toc
  • feedback
Django 3 Web Development Cookbook

Django 3 Web Development Cookbook

By : Aidas Bendoraitis, Jake Kronika
3.6 (9)
close
Django 3 Web Development Cookbook

Django 3 Web Development Cookbook

3.6 (9)
By: Aidas Bendoraitis, Jake Kronika

Overview of this book

Django is a web framework for perfectionists with deadlines, designed to help you build manageable medium and large web projects in a short time span. This fourth edition of the Django Web Development Cookbook is updated with Django 3's latest features to guide you effectively through the development process. This Django book starts by helping you create a virtual environment and project structure for building Python web apps. You'll learn how to build models, views, forms, and templates for your web apps and then integrate JavaScript in your Django apps to add more features. As you advance, you'll create responsive multilingual websites, ready to be shared on social networks. The book will take you through uploading and processing images, rendering data in HTML5, PDF, and Excel, using and creating APIs, and navigating different data types in Django. You'll become well-versed in security best practices and caching techniques to enhance your website's security and speed. This edition not only helps you work with the PostgreSQL database but also the MySQL database. You'll also discover advanced recipes for using Django with Docker and Ansible in development, staging, and production environments. By the end of this book, you will have become proficient in using Django's powerful features and will be equipped to create robust websites.
Table of Contents (15 chapters)
close

Adding database constraints

For better database integrity, it's common to define database constraints, telling some fields to be bound to fields of other database tables, making some fields unique or not null. For advanced database constraints, such as making the fields unique with a condition or setting specific conditions for the values of some fields, Django has special classes: UniqueConstraint and CheckConstraint. In this recipe, you will see a practical example of how to use them.

Getting ready

Let's start with the ideas app and the Idea model that will have at least title and author fields.

How to do it...

Set the database constraints in the Meta class of the Idea model as follows:

# myproject/apps/ideas/models.py
from django.db import models
from django.utils.translation import gettext_lazy as _


class Idea(models.Model):
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name=_("Author"),
on_delete=models.SET_NULL,
blank=True,
null=True,
related_name="authored_ideas",
)
title = models.CharField(
_("Title"),
max_length=200,
)

class Meta:
verbose_name = _("Idea")
verbose_name_plural = _("Ideas")
constraints = [
models.UniqueConstraint(
fields=["title"],
condition=~models.Q(author=None),
name="unique_titles_for_each_author",
),
models.CheckConstraint(
check=models.Q(
title__iregex=r"^\S.*\S$"
# starts with non-whitespace,
# ends with non-whitespace,
# anything in the middle
),
name="title_has_no_leading_and_trailing_whitespaces",
)
]

How it works...

We define two constraints in the database.

The first one, UniqueConstraint, tells the titles to be unique for each author. If the author is not set, the titles can be repeated. To check if the author is set we use the negated lookup: ~models.Q(author=None). Note that in Django, the ~ operator for lookups is equivalent to the exclude() method of a QuerySet, so these QuerySets are equivalent:

ideas_with_authors = Idea.objects.exclude(author=None)
ideas_with_authors2 = Idea.objects.filter(~models.Q(author=None))

The second constraint, CheckConstraint, checks if the title doesn't start and end with a whitespace. For that, we use a regular expression lookup.

There's more...

Database constraints don't affect form validation. They will just raise django.db.utils.IntegrityError if any data doesn't pass its conditions when saving entries to the database.

If you want to have data validated at the forms, you have to implement the validation in addition yourself, for example, in the clean() method of the model. That would look like this for the Idea model:

# myproject/apps/ideas/models.py
from django.db import models
from django.conf import settings
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _


class Idea(models.Model):
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
verbose_name=_("Author"),
on_delete=models.SET_NULL,
blank=True,
null=True,
related_name="authored_ideas2",
)
title = models.CharField(
_("Title"),
max_length=200,
)

# other fields and attributes…

class Meta:
verbose_name = _("Idea")
verbose_name_plural = _("Ideas")
constraints = [
models.UniqueConstraint(
fields=["title"],
condition=~models.Q(author=None),
name="unique_titles_for_each_author2",
),
models.CheckConstraint(
check=models.Q(
title__iregex=r"^\S.*\S$"
# starts with non-whitespace,
# ends with non-whitespace,
# anything in the middle
),
name="title_has_no_leading_and_trailing_whitespaces2",
)
]

def clean(self):
import re
if self.author and Idea.objects.exclude(pk=self.pk).filter(
author=self.author,
title=self.title,
).exists():
raise ValidationError(
_("Each idea of the same user should have a unique title.")
)
if not re.match(r"^\S.*\S$", self.title):
raise ValidationError(
_("The title cannot start or end with a whitespace.")
)

# other properties and methods…

See also

  • Chapter 3, Forms and Views
  • The Using database query expressions recipe in Chapter 10, Bells and Whistles
bookmark search playlist download font-size

Change the font size

margin-width

Change margin width

day-mode

Change background colour

Close icon Search
Country selected

Close icon Your notes and bookmarks

Delete Bookmark

Modal Close icon
Are you sure you want to delete it?
Cancel
Yes, Delete