Hur man skapar egna kommandon för django-adminLink to this heading

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:

Text
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.

För att implementera kommandot, redigera polls/management/commands/closepoll.py så att det ser ut så här:

Code
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)
            )

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.

Acceptera valfria argumentLink to this heading

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:

Code
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.

Hanteringskommandon och lokala språkLink to this heading

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:

Code
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.

TestarLink to this heading

Information om hur du testar anpassade hanteringskommandon finns i testing docs.

Åsidosätta kommandonLink to this heading

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.

KommandoobjektLink to this heading

class BaseCommandLink to this definition

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().

AttributLink to this heading

Alla attribut kan ställas in i din härledda klass och kan användas i BaseCommand’s subclasses.

BaseCommand.helpLink to this definition

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>.

BaseCommand.missing_args_messageLink to this definition

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”).

BaseCommand.output_transactionLink to this definition

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.

BaseCommand.requires_migrations_checksLink to this definition

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.

BaseCommand.requires_system_checksLink to this definition

En lista eller tupel av taggar, t.ex. [Tags.staticfiles, Tags.models]. Systemkontroller registrerade i de valda taggarna 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__'.

BaseCommand.styleLink to this definition

Ett instansattribut som hjälper till att skapa färgade utdata när du skriver till stdout eller stderr. Till exempel:

Code
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.

BaseCommand.suppressed_base_argumentsLink to this definition

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.

MetoderLink to this heading

BaseCommand har några metoder som kan åsidosättas men endast metoden handle() måste implementeras.

BaseCommand.create_parser(prog_name, subcommand, **kwargs)Link to this definition

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.

BaseCommand.add_arguments(parser)Link to this definition

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.

BaseCommand.get_version()Link to this definition

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.

BaseCommand.execute(*args, **options)Link to this definition

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.

BaseCommand.handle(*args, **options)Link to this definition

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).

BaseCommand.check(app_configs=None, tags=None, display_num_errors=False, include_deployment_checks=False, fail_level=checks.ERROR, databases=None)Link to this definition

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.

BaseCommand.get_check_kwargs(options)Link to this definition

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:

Code
def get_check_kwargs(self, options):
    kwargs = super().get_check_kwargs(options)
    return {**kwargs, "databases": [options["database"]]}

underklasser till BaseCommandLink to this heading

class AppCommandLink to this definition

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.

AppCommand.handle_app_config(app_config, **options)Link to this definition

Utför kommandots åtgärder för app_config, som kommer att vara en AppConfig-instans som motsvarar en applikationsetikett som anges på kommandoraden.

class LabelCommandLink to this definition

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.

LabelCommand.labelLink to this definition

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'.

LabelCommand.handle_label(label, **options)Link to this definition

Utför kommandots åtgärder för label, som kommer att vara den sträng som anges på kommandoraden.

Undantag för kommandonLink to this heading

exception CommandError(returncode=1)Link to this definition

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.