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

Creating a model mixin with URL-related methods

For every model that has its own distinct detail page, it is good practice to define the get_absolute_url() method. This method can be used in templates and also in the Django admin site to preview the saved object. However, get_absolute_url() is ambiguous, as it returns the URL path instead of the full URL.

In this recipe, we will look at how to create a model mixin that provides simplified support for model-specific URLs. This mixin will enable you to do the following:

  • Allow you to define either the URL path or the full URL in your model
  • Generate the other URL automatically, based on the one that you defined
  • Define the get_absolute_url() method behind the scenes

Getting ready

If you haven't yet done so, create the myproject.apps.core app where you will store your model mixins. Then, create a models.py file in the core package. Alternatively, if you create a reusable app, put the mixins in a base.py file in that app.

How to do it...

Execute the following steps, one by one:

  1. Add the following content to the models.py file of your core app:
# myproject/apps/core/models.py
from urllib.parse import urlparse, urlunparse
from django.conf import settings
from django.db import models

class UrlBase(models.Model):
"""
A replacement for get_absolute_url()
Models extending this mixin should have either get_url or
get_url_path implemented.
"""
class Meta:
abstract = True

def get_url(self):
if hasattr(self.get_url_path, "dont_recurse"):
raise NotImplementedError
try:
path = self.get_url_path()
except NotImplementedError:
raise
return settings.WEBSITE_URL + path
get_url.dont_recurse = True

def get_url_path(self):
if hasattr(self.get_url, "dont_recurse"):
raise NotImplementedError
try:
url = self.get_url()
except NotImplementedError:
raise
bits = urlparse(url)
return urlunparse(("", "") + bits[2:])
get_url_path.dont_recurse = True

def get_absolute_url(self):
return self.get_url()
  1. Add the WEBSITE_URL setting without a trailing slash to the dev, test, staging, and production settings. For example, for the development environment this will be as follows:
# myproject/settings/dev.py
from
._base import *

DEBUG = True
WEBSITE_URL = "http://127.0.0.1:8000" # without trailing slash
  1. To use the mixin in your app, import the mixin from the core app, inherit the mixin in your model class, and define the get_url_path() method, as follows:
# myproject/apps/ideas/models.py
from django.db import models
from django.urls import reverse
from django.utils.translation import gettext_lazy as _

from myproject.apps.core.models import UrlBase

class Idea(UrlBase):
# fields, attributes, properties and methods…

def get_url_path(self):
return reverse("idea_details", kwargs={
"idea_id": str(self.pk),
})

How it works...

The UrlBase class is an abstract model that has three methods, as follows:

  • get_url() retrieves the full URL of the object.
  • get_url_path() retrieves the absolute path of the object.
  • get_absolute_url() mimics the get_url_path() method.

The get_url() and get_url_path() methods are expected to be overwritten in the extended model class, for example, Idea. You can define get_url(), and get_url_path() will strip it to the path. Alternatively, you can define get_url_path(), and get_url() will prepend the website URL to the beginning of the path.

The rule of thumb is to always overwrite the get_url_path() method.

In the templates, use get_url_path() when you need a link to an object on the same website, as follows:

<a href="{{ idea.get_url_path }}">{{ idea.title }}</a>

Use get_url() for links in external communication, such as in emails, RSS feeds, or APIs; an example is as follows:

<a href="{{ 
idea.get_url }}">{{ idea.title }}</a>

The default get_absolute_url() method will be used in the Django model administration for the View on site functionality, and might also be used by some third-party Django apps.

There's more...

In general, don't use incremental primary keys in the URLs, because it is not safe to expose them to the end user: the total amount of items would be visible, and it would be too easy to navigate through different items by just changing the URL path.

You can use the primary keys in the URLs for the detail pages only if they are Universal Unique Identifiers (UUIDs) or generated random strings. Otherwise, create and use a slug field, as follows:

class Idea(UrlBase):
slug = models.SlugField(_("Slug for URLs"), max_length=50)

See also

  • The Using model mixins recipe
  • The Creating a model mixin to handle creation and modification dates recipe
  • The Creating a model mixin to take care of meta tags recipe
  • The Creating a model mixin to handle generic relations recipe
  • The Configuring settings for development, testing, staging, and production environments recipe, in Chapter 1, Getting Started with Django 3.0
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