For deployment purposes, a command which can update the domain of a Wagtail website can be useful.

You can create a custom management command which helps you doing this. Start with creating a file <app>/management/commands/wagtail_change_site_domain.py.

You can call the command as follows:

./manage.py wagtail_change_site_domain --site_id=1 --new_site_domain=yellowduck.be:443

The implementation is like this:

<app>/management/commands/wagtail_change_site_domain.py

from django.core.management.base import BaseCommand
 
from wagtail.core.models import Site
 
class Command(BaseCommand):
"""
Change site domain and port for wagtail.
Example:
./manage.py wagtail_change_site_domain --site_id=2 --new_site_domain=yellowduck.be:443
"""
 
def add_arguments(self, parser):
parser.add_argument("--site_id", type=int, default=1)
parser.add_argument("--new_site_domain", required=True)
 
def handle(self, *args, **options):
 
site_id = options["site_id"]
new_site_domain = options["new_site_domain"]
 
domain = new_site_domain
port = 80
if ":" in new_site_domain:
domain, port = new_site_domain.split(":")
 
try:
site = Site.objects.get(pk=site_id)
site.hostname = domain
site.port = port
site.save()
 
self.stdout.write(f"Domain changed to {new_site_domain}")
except Site.DoesNotExist:
self.stderr.write(f"No site with id {site_id}"")

The add_arguments allows us to easily define the required and options arguments for the command. We define 2 of them: --site_id and --new_site_domain.

The handle function is called when you run the command.

We start with parsing the command-line arguments. For the port and domain, we check if it's specified in the argument new_site_domain and use that if specified. We wrap this in a try/catch to properly handle an invalid --site_id value.

We then lookup the site by it's ID using the Site model, set the hostname and port and save it.