Django 2.1 - Writing custom django-admin commands

कस्टम django- व्यवस्थापक कमांड लिखना




django

कस्टम django- व्यवस्थापक कमांड लिखना

अनुप्रयोग अपनी स्वयं की क्रियाओं को manage.py कर सकते हैं। उदाहरण के लिए, आप एक Django ऐप जो आप वितरित कर रहे हैं, के लिए एक manage.py एक्शन जोड़ना चाह सकते हैं। इस दस्तावेज़ में, हम tutorial से polls एप्लिकेशन के लिए एक कस्टम closepoll कमांड का निर्माण करेंगे।

ऐसा करने के लिए, एप्लिकेशन में केवल एक management/commands निर्देशिका जोड़ें। Django उस निर्देशिका में प्रत्येक पायथन मॉड्यूल के लिए एक manage.py कमांड दर्ज करेगा जिसका नाम अंडरस्कोर के साथ शुरू नहीं होता है। उदाहरण के लिए:

polls/
    __init__.py
    models.py
    management/
        commands/
            _private.py
            closepoll.py
    tests.py
    views.py

इस उदाहरण में, closepoll कमांड को किसी भी परियोजना के लिए उपलब्ध कराया जाएगा जिसमें INSTALLED_APPS में polls आवेदन शामिल है।

_private.py मॉड्यूल एक प्रबंधन कमांड के रूप में उपलब्ध नहीं होगा।

closepoll.py मॉड्यूल की केवल एक आवश्यकता होती है - यह एक क्लास Command को परिभाषित करना चाहिए जो BaseCommand या उसके किसी subclasses का विस्तार करता है।

स्टैंडअलोन स्क्रिप्ट

कस्टम प्रबंधन कमांड विशेष रूप से स्टैंडअलोन स्क्रिप्ट चलाने के लिए या स्क्रिप्ट के लिए उपयोगी होते हैं जो समय-समय पर यूनिक्स क्रेस्टैब या विंडोज शेड्यूल किए गए कार्य नियंत्रण पैनल से निष्पादित होते हैं।

कमांड को लागू करने के लिए, इस तरह polls/management/commands/closepoll.py लिए polls/management/commands/closepoll.py संपादित करें:

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_id', nargs='+', type=int)

    def handle(self, *args, **options):
        for poll_id in options['poll_id']:
            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))

ध्यान दें

जब आप प्रबंधन आदेशों का उपयोग कर रहे हैं और कंसोल आउटपुट प्रदान करना चाहते हैं, तो आपको सीधे stdout और stderr प्रिंट करने के बजाय self.stdout और self.stderr लिखना चाहिए। इन प्रॉक्सी का उपयोग करके, अपने कस्टम कमांड का परीक्षण करना बहुत आसान हो जाता है। यह भी ध्यान दें कि आपको नए वर्ण के साथ संदेशों को समाप्त करने की आवश्यकता नहीं है, यह स्वचालित रूप से जोड़ा जाएगा, जब तक कि आप ending पैरामीटर निर्दिष्ट नहीं करते हैं:

self.stdout.write("Unterminated line", ending='')

नए कस्टम कमांड को python manage.py closepoll <poll_id> का उपयोग करके बुलाया जा सकता है।

handle() विधि एक या एक से अधिक poll_ids ले poll_ids और प्रत्येक के लिए poll.opened करने के लिए poll.opened को सेट poll.opened है। यदि उपयोगकर्ता ने किसी भी गैर-मतदान सर्वेक्षण का संदर्भ दिया है, तो एक CommandError उठाया जाता है। poll.opened विशेषता tutorial में मौजूद नहीं है और इस उदाहरण के लिए polls.models.Question में जोड़ा गया था।

वैकल्पिक तर्क स्वीकार करना

एक ही closepoll को अतिरिक्त कमांड लाइन विकल्पों को स्वीकार करके इसे बंद करने के बजाय किसी closepoll पोल को हटाने के लिए आसानी से संशोधित किया जा सकता है। ये कस्टम विकल्प add_arguments() विधि में इस तरह जोड़े जा सकते हैं:

class Command(BaseCommand):
    def add_arguments(self, parser):
        # Positional arguments
        parser.add_argument('poll_id', nargs='+', type=int)

        # Named (optional) arguments
        parser.add_argument(
            '--delete',
            action='store_true',
            dest='delete',
            help='Delete poll instead of closing it',
        )

    def handle(self, *args, **options):
        # ...
        if options['delete']:
            poll.delete()
        # ...

विकल्प (हमारे उदाहरण में delete ) हैंडल विधि के विकल्प हुकुम पैरामीटर में उपलब्ध है। add_argument उपयोग के बारे में अधिक जानकारी के लिए argparse पायथन दस्तावेज़ देखें।

कस्टम कमांड लाइन विकल्प जोड़ने में सक्षम होने के अलावा, सभी प्रबंधन कमांड कुछ डिफ़ॉल्ट विकल्पों जैसे --verbosity और --traceback को स्वीकार कर सकते हैं।

प्रबंधन आदेश और स्थान

डिफ़ॉल्ट रूप से, प्रबंधन कमांड को वर्तमान सक्रिय लोकेल के साथ निष्पादित किया जाता है।

यदि, किसी कारण से, आपके कस्टम प्रबंधन कमांड को सक्रिय लोकेल के बिना चलना चाहिए (उदाहरण के लिए, अनुवादित सामग्री को डेटाबेस में डालने से रोकने के लिए), तो अपने handle() विधि पर @no_translations डेकोरेटर का उपयोग करके अनुवादों को निष्क्रिय करें:

from django.core.management.base import BaseCommand, no_translations

class Command(BaseCommand):
    ...

    @no_translations
    def handle(self, *args, **options):
        ...

चूंकि अनुवाद निष्क्रियकरण के लिए कॉन्फ़िगर सेटिंग्स तक पहुंच की आवश्यकता होती है, डेकोरेटर का उपयोग उन कमांड के लिए नहीं किया जा सकता है जो कॉन्फ़िगर सेटिंग्स के बिना काम करते हैं।

Django 2.1 में परिवर्तित:

@no_translations डेकोरेटर नया है। पुराने संस्करणों में, कमांड चलाने से पहले अनुवादों को निष्क्रिय कर दिया जाता है जब तक कि कमांड का leave_locale_alone विशेषता (अब हटा दिया गया) True सेट न हो।

परिक्षण

कस्टम प्रबंधन आदेशों का परीक्षण करने की जानकारी परीक्षण डॉक्स में पाई जा सकती है।

ओवरराइडिंग कमांड्स

Django बिल्ट-इन कमांड्स को पंजीकृत करता है और फिर INSTALLED_APPS में रिवर्स में कमांड खोजता है। खोज के दौरान, यदि कोई कमांड नाम पहले से पंजीकृत कमांड को डुप्लिकेट करता है, तो नया खोजा गया कमांड पहले ओवरराइड करता है।

दूसरे शब्दों में, एक कमांड को ओवरराइड करने के लिए, नए कमांड में एक ही नाम होना चाहिए और INSTALLED_APPS में ओवरराइड कमांड के ऐप से पहले इसका ऐप होना चाहिए।

तृतीय-पक्ष एप्लिकेशन से प्रबंधन आदेश जिन्हें अनजाने में ओवरराइड किया गया है, उन्हें आपके प्रोजेक्ट के एक ऐप में एक नया कमांड बनाकर उपलब्ध कराया जा सकता है ( INSTALLED_APPS में तीसरे पक्ष के ऐप से पहले आदेश दिया गया) जो ओवरराइड कमांड की Command को आयात करता है ।

कमांड ऑब्जेक्ट्स

class BaseCommand [source]

आधार वर्ग जिसमें से सभी प्रबंधन अंतत: व्युत्पन्न होते हैं।

यदि आप उन सभी तंत्रों तक पहुँच चाहते हैं, जो कमांड-लाइन तर्कों को पार्स करते हैं और प्रतिक्रिया में कॉल करने के लिए किस कोड पर काम करते हैं; यदि आपको उस व्यवहार को बदलने की आवश्यकता नहीं है, तो उसके किसी subclasses का उपयोग करने पर विचार करें।

BaseCommand वर्ग को BaseCommand वर्ग में रखने के लिए आवश्यक है कि आप handle() पद्धति को लागू करें।

गुण

सभी विशेषताओं को आपके व्युत्पन्न वर्ग में सेट किया जा सकता है और इसका उपयोग BaseCommand के subclasses में किया जा सकता है।

BaseCommand.help

कमांड का एक संक्षिप्त विवरण, जो हेल्प संदेश में तब प्रिंट किया जाएगा जब उपयोगकर्ता कमांड python manage.py help <command>

BaseCommand.missing_args_message

यदि आपका आदेश अनिवार्य स्थिति संबंधी तर्कों को परिभाषित करता है, तो आप लापता तर्कों के मामले में दी गई संदेश त्रुटि को अनुकूलित कर सकते हैं। डिफ़ॉल्ट रूप से argparse द्वारा आउटपुट है ("बहुत कम तर्क")।

BaseCommand.output_transaction

एक बूलियन यह दर्शाता है कि कमांड SQL स्टेटमेंट को आउटपुट करता है या नहीं; अगर यह True , तो आउटपुट स्वचालित रूप से BEGIN; साथ लिपट जाएगा BEGIN; और COMMIT; । डिफ़ॉल्ट मान False

BaseCommand.requires_migrations_checks

एक बूलियन; यदि True , तो कमांड चेतावनी देता है यदि डिस्क पर माइग्रेशन का सेट डेटाबेस में माइग्रेशन से मेल नहीं खाता है। एक चेतावनी कमांड को निष्पादित करने से नहीं रोकती है। डिफ़ॉल्ट मान False

BaseCommand.requires_system_checks

एक बूलियन; यदि True , तो संपूर्ण Django प्रोजेक्ट को कमांड निष्पादित करने से पहले संभावित समस्याओं के लिए जाँच की जाएगी। डिफ़ॉल्ट मान True

BaseCommand.style

एक उदाहरण विशेषता जो stdout या stderr को लिखते समय रंगीन आउटपुट बनाने में मदद करती है। उदाहरण के लिए:

self.stdout.write(self.style.SUCCESS('...'))

रंग पैलेट को संशोधित करने और उपलब्ध शैलियों को देखने के लिए सीखने के लिए सिंटैक्स रंग देखें (उस अनुभाग में वर्णित "भूमिकाओं" के बड़े संस्करणों का उपयोग करें)।

यदि आप अपने आदेश को चलाते समय self.style() --no-color विकल्प पास करते हैं, तो सभी self.style() कॉल मूल स्ट्रिंग को बिना लौटाए वापस कर देंगे।

तरीके

BaseCommand की कुछ विधियाँ हैं जिन्हें ओवरराइड किया जा सकता है लेकिन केवल handle() पद्धति को ही लागू किया जाना चाहिए।

एक उपवर्ग में एक कंस्ट्रक्टर को लागू करना

यदि आप BaseCommand उपवर्ग में __init__ को लागू करते हैं, तो आपको BaseCommand के __init__ को कॉल करना होगा:

class Command(BaseCommand):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # ...
BaseCommand.add_arguments(parser) [source]

कमांड लाइन तर्क को कमांड में पारित करने के लिए पार्सर तर्कों को जोड़ने के लिए प्रवेश बिंदु। कस्टम कमांड्स को इस विधि को ओवरराइड करना चाहिए ताकि कमांड द्वारा स्वीकार की गई स्थिति और वैकल्पिक तर्क दोनों को जोड़ा जा सके। BaseCommand कॉलिंग super() की आवश्यकता नहीं है जब सीधे BaseCommand

BaseCommand.get_version() [source]

Django संस्करण लौटाता है, जो सभी अंतर्निहित Django आदेशों के लिए सही होना चाहिए। उपयोगकर्ता-प्रदत्त कमांड्स अपने स्वयं के संस्करण को वापस करने के लिए इस पद्धति को ओवरराइड कर सकते हैं।

BaseCommand.execute(*args, **options) [source]

इस कमांड को निष्पादित करने की कोशिश करता है, यदि आवश्यक हो तो सिस्टम जांच कर रहा है (जैसा कि requires_system_checks विशेषता द्वारा नियंत्रित किया जाता है)। यदि कमांड एक कमांडर को उठाता है, तो इसे इंटरसेप्ट किया जाता है और CommandError मुद्रित किया जाता है।

अपने कोड में एक प्रबंधन कमांड कॉल करना

एक कमांड निष्पादित करने के लिए अपने कोड से सीधे execute() नहीं कहा जाना चाहिए। इसके बजाय call_command() उपयोग करें।

BaseCommand.handle(*args, **options) [source]

आज्ञा का वास्तविक तर्क। उपवर्गों को इस विधि को लागू करना चाहिए।

यह एक स्ट्रिंग लौटा सकता है जिसे stdout ( BEGIN; द्वारा लिपटा हुआ BEGIN; और COMMIT; यदि output_transaction True ) पर मुद्रित किया जाएगा।

BaseCommand.check(app_configs=None, tags=None, display_num_errors=False) [source]

संभावित समस्याओं के लिए पूरे Django परियोजना का निरीक्षण करने के लिए सिस्टम चेक फ्रेमवर्क का उपयोग करता है। गंभीर समस्याओं को एक CommandError रूप में उठाया जाता है; चेतावनी stderr के लिए उत्पादन कर रहे हैं; मामूली सूचनाएं स्टडआउट के लिए आउटपुट हैं।

यदि app_configs और tags दोनों None , तो सभी सिस्टम चेक किए जाते हैं। tags चेक टैग की सूची हो सकते हैं, जैसे compatibility या models

BaseCommand उपवर्ग

class AppCommand

एक प्रबंधन कमांड जो तर्क के रूप में एक या एक से अधिक स्थापित एप्लिकेशन लेबल लेता है, और उनमें से प्रत्येक के साथ कुछ करता है।

handle() लागू handle() बजाय, उपवर्गों को handle_app_config() को लागू करना होगा, जिसे प्रत्येक एप्लिकेशन के लिए एक बार कॉल किया जाएगा।

AppCommand.handle_app_config(app_config, **options)

app_config लिए कमांड की क्रियाएं करें, जो कमांड लाइन पर दिए गए एप्लिकेशन लेबल के अनुरूप एक AppConfig उदाहरण होगा।

class LabelCommand

एक प्रबंधन कमांड जो कमांड लाइन पर एक या अधिक मनमानी तर्क (लेबल) लेता है, और उनमें से प्रत्येक के साथ कुछ करता है।

handle() लागू handle() बजाय, उपवर्गों को handle_label() को लागू करना होगा, जिसे प्रत्येक लेबल के लिए एक बार कॉल किया जाएगा।

LabelCommand.label

एक स्ट्रिंग जो मनमानी तर्कों का वर्णन करती है, जो कमांड को दी जाती है। स्ट्रिंग का उपयोग कमांड के उपयोग पाठ और त्रुटि संदेशों में किया जाता है। 'label' कमी।

LabelCommand.handle_label(label, **options)

label लिए कमांड की क्रियाएं करें, जो कमांड लाइन पर दी गई स्ट्रिंग होगी।

कमान अपवाद

exception CommandError [source]

प्रबंधन आदेश निष्पादित करते समय अपवाद वर्ग एक समस्या का संकेत देता है।

यदि यह अपवाद एक कमांड लाइन कंसोल से प्रबंधन कमांड के निष्पादन के दौरान उठाया जाता है, तो इसे पकड़ा जाएगा और एक अच्छी तरह से मुद्रित त्रुटि संदेश को उचित आउटपुट स्ट्रीम (यानी, स्टादर) में बदल दिया जाएगा; परिणामस्वरूप, इस अपवाद को उठाना (त्रुटि के एक समझदार विवरण के साथ) यह इंगित करने का पसंदीदा तरीका है कि कमांड के निष्पादन में कुछ गलत हो गया है।

यदि एक प्रबंधन कमांड को call_command() के माध्यम से कोड से कॉल किया जाता है, तो यह आपके ऊपर है कि आप कब अपवाद को पकड़ सकते हैं।