django-admin¶Program kan registrera sina egna åtgärder med manage.py. Du kanske till exempel vill lägga till en manage.py-åtgärd för en Django-app som du distribuerar. I det här dokumentet kommer vi att bygga ett anpassat closepoll-kommando för applikationen polls från tutorial.
För att göra detta, lägg till en management/commands katalog i applikationen. Django kommer att registrera ett manage.py-kommando för varje Python-modul i den katalogen vars namn inte börjar med ett understreck. Till exempel:
polls/
__init__.py
models.py
management/
__init__.py
commands/
__init__.py
_private.py
closepoll.py
tests.py
views.py
I det här exemplet kommer kommandot closepoll att göras tillgängligt för alla projekt som innehåller applikationen polls i INSTALLED_APPS.
Modulen _private.py kommer inte att vara tillgänglig som ett hanteringskommando.
Modulen closepoll.py har bara ett krav – den måste definiera en klass Command som utökar BaseCommand eller en av dess subclasses.
Fristående skript
Anpassade hanteringskommandon är särskilt användbara för att köra fristående skript eller för skript som regelbundet körs från UNIX crontab eller från kontrollpanelen för schemalagda uppgifter i Windows.
För att implementera kommandot, redigera polls/management/commands/closepoll.py så att det ser ut så här:
from django.core.management.base import BaseCommand, CommandError
from polls.models import Question as Poll
class Command(BaseCommand):
help = "Closes the specified poll for voting"
def add_arguments(self, parser):
parser.add_argument("poll_ids", nargs="+", type=int)
def handle(self, *args, **options):
for poll_id in options["poll_ids"]:
try:
poll = Poll.objects.get(pk=poll_id)
except Poll.DoesNotExist:
raise CommandError('Poll "%s" does not exist' % poll_id)
poll.opened = False
poll.save()
self.stdout.write(
self.style.SUCCESS('Successfully closed poll "%s"' % poll_id)
)
Observera
När du använder hanteringskommandon och vill tillhandahålla konsolutdata bör du skriva till self.stdout och self.stderr i stället för att skriva ut direkt till stdout och stderr. Genom att använda dessa proxyer blir det mycket enklare att testa ditt anpassade kommando. Observera också att du inte behöver avsluta meddelanden med ett nytt radtecken, det läggs till automatiskt om du inte anger parametern ending:
self.stdout.write("Unterminated line", ending="")
Det nya anpassade kommandot kan anropas med hjälp av python manage.py closepoll <poll_ids>.
Metoden handle() tar ett eller flera poll_ids och sätter poll.opened till False för varje. Om användaren refererar till en icke-existerande enkät genereras ett CommandError. Attributet poll.opened finns inte i tutorial och lades till i polls.models.Question för detta exempel.
Samma closepoll kan enkelt modifieras för att ta bort en viss undersökning i stället för att stänga den genom att acceptera ytterligare kommandoradsalternativ. Dessa anpassade alternativ kan läggas till i add_arguments()-metoden så här:
class Command(BaseCommand):
def add_arguments(self, parser):
# Positional arguments
parser.add_argument("poll_ids", nargs="+", type=int)
# Named (optional) arguments
parser.add_argument(
"--delete",
action="store_true",
help="Delete poll instead of closing it",
)
def handle(self, *args, **options):
# ...
if options["delete"]:
poll.delete()
# ...
Alternativet (delete i vårt exempel) finns tillgängligt i options dict-parametern i handle-metoden. Se Python-dokumentationen för argparse för mer information om hur add_argument används.
Förutom att kunna lägga till egna kommandoradsalternativ kan alla hanteringskommandon acceptera vissa standardalternativ som --verbosity och --traceback.
Som standard utförs hanteringskommandon med den aktuella aktiva språkdräkten.
Om ditt anpassade hanteringskommando av någon anledning måste köras utan en aktiv lokal (t.ex. för att förhindra att översatt innehåll infogas i databasen), avaktiverar du översättningar med hjälp av dekoratorn @no_translations på din handle()-metod:
from django.core.management.base import BaseCommand, no_translations
class Command(BaseCommand):
...
@no_translations
def handle(self, *args, **options): ...
Eftersom avaktivering av översättning kräver tillgång till konfigurerade inställningar kan dekoratorn inte användas för kommandon som fungerar utan konfigurerade inställningar.
Information om hur du testar anpassade hanteringskommandon finns i testing docs.
Django registrerar de inbyggda kommandona och söker sedan efter kommandon i INSTALLED_APPS i omvänd ordning. Under sökningen, om ett kommandonamn duplicerar ett redan registrerat kommando, åsidosätter det nyupptäckta kommandot det första.
Med andra ord, för att åsidosätta ett kommando måste det nya kommandot ha samma namn och dess app måste ligga före det åsidosatta kommandots app i INSTALLED_APPS.
Hanteringskommandon från tredjepartsappar som oavsiktligt har åsidosatts kan göras tillgängliga under ett nytt namn genom att skapa ett nytt kommando i en av projektets appar (rangordnat före tredjepartsappen i INSTALLED_APPS) som importerar Command för det åsidosatta kommandot.
Basklassen som alla managementkommandon i slutändan härrör från.
Använd den här klassen om du vill ha tillgång till alla mekanismer som analyserar kommandoradsargumenten och räknar ut vilken kod som ska anropas som svar; om du inte behöver ändra något av det beteendet, överväg att använda en av dess subclasses.
Underklassning av klassen BaseCommand kräver att du implementerar metoden handle().
Alla attribut kan ställas in i din härledda klass och kan användas i BaseCommand’s subclasses.
En kort beskrivning av kommandot som kommer att skrivas ut i hjälpmeddelandet när användaren kör kommandot python manage.py help <command>.
Om ditt kommando definierar obligatoriska positionella argument kan du anpassa det felmeddelande som returneras om argument saknas. Standardvärdet är det som matas ut av argparse (”för få argument”).
Ett booleskt värde som anger om kommandot matar ut SQL-satser; om True, kommer utdata automatiskt att omslutas av BEGIN; och COMMIT;. Standardvärdet är False.
Ett boolean; om True, skriver kommandot ut en varning om uppsättningen migreringar på disken inte stämmer överens med migreringarna i databasen. En varning hindrar inte kommandot från att utföras. Standardvärdet är False.
En lista eller tupel av taggar, t.ex. [Tags.staticfiles, Tags.models]. Systemkontroller :ref:registrerade i de valda taggarna <registering-labeling-checks> kommer att kontrolleras för fel innan kommandot utförs. Värdet '__all__' kan användas för att ange att alla systemkontroller ska utföras. Standardvärdet är '__all__'.
Ett instansattribut som hjälper till att skapa färgade utdata när du skriver till stdout eller stderr. Till exempel:
self.stdout.write(self.style.SUCCESS("..."))
Se Syntax färgläggning för att lära dig hur du ändrar färgpaletten och för att se de tillgängliga stilarna (använd versaler av ”rollerna” som beskrivs i det avsnittet).
Om du anger alternativet --no-color när du kör ditt kommando kommer alla anrop av self.style() att returnera originalsträngen ofärgad.
Standardkommandovalternativen som ska undertryckas i hjälputmatningen. Detta bör vara en uppsättning alternativnamn (t.ex. '--verbosity'). Standardvärdena för de undertryckta alternativen skickas fortfarande.
BaseCommand har några metoder som kan åsidosättas men endast metoden handle() måste implementeras.
Implementera en konstruktor i en subklass
Om du implementerar __init__ i din subklass av BaseCommand måste du anropa BaseCommand:s __init__:
class Command(BaseCommand):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# ...
Returnerar en CommandParser-instans, som är en ArgumentParser-underklass med några anpassningar för Django.
Du kan anpassa instansen genom att åsidosätta den här metoden och anropa super() med kwargs av ArgumentParser-parametrar.
Ingångspunkt för att lägga till parserargument för att hantera kommandoradsargument som skickas till kommandot. Anpassade kommandon bör åsidosätta denna metod för att lägga till både positionella och valfria argument som accepteras av kommandot. Anrop av super() behövs inte vid direkt subklassning av BaseCommand.
Returnerar Django-versionen, som bör vara korrekt för alla inbyggda Django-kommandon. Användartillhandahållna kommandon kan åsidosätta den här metoden för att returnera sin egen version.
Försöker köra kommandot och utför systemkontroller om det behövs (styrs av attributet requires_system_checks). Om kommandot ger upphov till ett CommandError, fångas det upp och skrivs ut till stderr.
Anropa ett management-kommando i din kod
execute() ska inte anropas direkt från din kod för att utföra ett kommando. Använd call_command() istället.
Den faktiska logiken i kommandot. Underklasser måste implementera denna metod.
Den kan returnera en sträng som kommer att skrivas ut till stdout (omsluten av BEGIN; och COMMIT; om output_transaction är True).
Använder ramverket för systemkontroll för att inspektera hela Django-projektet för potentiella problem. Allvarliga problem tas upp som ett CommandError; varningar skickas ut till stderr; mindre meddelanden skickas ut till stdout.
Om app_configs och tags båda är None utförs alla systemkontroller utom distributions- och databasrelaterade kontroller. tags kan vara en lista med kontrolltaggar, t.ex. compatibility eller models.
Du kan ange include_deployment_checks=True för att även utföra deployment-kontroller och en lista med databasalias i databases för att köra databasrelaterade kontroller mot dem.
Tillhandahåller kwargs för anropet till check(), inklusive omvandling av värdet av requires_system_checks till kwarg tag.
Åsidosätt denna metod för att ändra de värden som anges i check(). Om du t.ex. vill välja databasrelaterade kontroller kan du åsidosätta get_check_kwargs() enligt följande:
def get_check_kwargs(self, options):
kwargs = super().get_check_kwargs(options)
return {**kwargs, "databases": [options["database"]]}
BaseCommand¶Ett managementkommando som tar en eller flera installerade applikationsetiketter som argument och gör något med var och en av dem.
I stället för att implementera handle() måste underklasser implementera handle_app_config(), som anropas en gång för varje applikation.
Utför kommandots åtgärder för app_config, som kommer att vara en AppConfig-instans som motsvarar en applikationsetikett som anges på kommandoraden.
Ett managementkommando som tar ett eller flera godtyckliga argument (etiketter) på kommandoraden och gör något med vart och ett av dem.
I stället för att implementera handle() måste underklasser implementera handle_label(), som anropas en gång för varje etikett.
En sträng som beskriver de godtyckliga argument som skickas till kommandot. Strängen används i kommandots användningstext och felmeddelanden. Standardvärdet är 'label'.
Utför kommandots åtgärder för label, som kommer att vara den sträng som anges på kommandoraden.
Undantagsklass som indikerar ett problem under utförandet av ett managementkommando.
Om detta undantag uppstår under exekveringen av ett managementkommando från en kommandoradskonsol, kommer det att fångas upp och omvandlas till ett snyggt utskrivet felmeddelande till lämplig utdataström (t.ex. stderr); därför är det bästa sättet att ange att något har gått fel under exekveringen av ett kommando att skapa detta undantag (med en vettig beskrivning av felet). Det accepterar det valfria argumentet returncode för att anpassa avslutningsstatusen för hanteringskommandot att avslutas med, med hjälp av sys.exit().
Om ett managementkommando anropas från kod genom call_command(), är det upp till dig att fånga upp undantaget när det behövs.
aug. 11, 2025