Tive exatamente o mesmo problema que o seu. Implementei um script de monitoramento usando a biblioteca watchdogs e, ao final de "wait_timeout", o erro do MySQL seria gerado.
Após algumas tentativas com a função "django.db.close_old_connections()", ainda não funcionou, mas eu estava tentando fechar conexões antigas a cada intervalo de tempo definido, o que não estava funcionando. Alterei o comando close para rodar apenas antes da chamada do meu comando custom management (que é o comando que irá interagir com o db e usado para travar com o erro do MySQL) e ele começou a funcionar.
Aparentemente, de esta página , a razão pela qual isso acontece é porque a função "close_old_connection" está vinculada apenas a sinais de solicitação HTTP, portanto, ela não será acionada em scripts personalizados específicos. A documentação do Django não diz isso, e eu honestamente também entendi as coisas da mesma forma que você estava entendendo.
Então, o que você pode tentar fazer é adicionar a chamada para fechar a conexão antiga antes de interagir com o db:
from django.db import close_old_connections
close_old_connections()
do_something_with_db()