中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Django中怎么創建自定義命令

發布時間:2021-06-12 11:03:21 來源:億速云 閱讀:200 作者:小新 欄目:編程語言

小編給大家分享一下Django中怎么創建自定義命令,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

在開發Django項目時,有時候需要編寫一次性腳本來自動化特定任務。
例如:
1、清理錯誤的數據列
2、導入初始數據庫數據
我們可以通過兩種方式在django中運行這些類型的命令。第一是編寫一個普通的python腳本,然后可以通過運行python file_name.py來調用它,而另一個方法是使用django-admin命令。這些是通過調用python manage.py command_name運行的。

對于這篇文章,我將通過一個博客應用程序進行演示,該應用程序只有3個數據庫表:User,Category和Post。
普通的python腳本方法
對于第一個示例,我們將嘗試使用以下腳本列出所有系統用戶:

from django.contrib.auth import get_user_model

User = get_user_model()

# retrieve all users
users = User.objects.all()

# loop through all usersfor user in users:
    print(f'user is {user.get_full_name()} and their username is {user.get_username()}')

可以命名腳本list_users.py并通過python list_users.py運行它,但運行的時候會遇到如下錯誤:

django.core.exceptions.ImproperlyConfigured: Requested setting AUTH_USER_MODEL, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings

可能有人會假設,如果腳本位于django的項目目錄中,腳本可以正常運行。然而,這種情況也不對。這是因為腳本不知道該腳本將應用于哪個項目。因為我們可能在一臺計算機或虛擬環境中有多個項目。因此,給腳本一些上下文信息很重要。

我們將通過稍微修改腳本來做到這一點。

import os

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'projectname.settings')import django
django.setup()from django.contrib.auth import get_user_model

User = get_user_model()

users = User.objects.all()for user in users:print(f'user is {user.get_full_name()} and their username is {user.get_username()}')

在這里,我們指定項目的設置,不僅如此,還可以調用django.setup()方法。該方法配置設置,記錄日志并填充應用程序注冊表。總之,我們要使腳本知道我們的項目上下文。

請注意,導入順序很重要,不要調整,這里有坑。

如果再次運行腳本,則所有用戶都會正常打印到終端,沒有報錯了。

接下來,我們將通過運行django-admin startapp posts來創建一個名為posts的app應用。

該應用程序將包含我們的博客文章模型

from django.db import modelsfrom django.contrib.auth import get_user_model

User = get_user_model()# Create your models here.class CommonInfo(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)class Meta:
        abstract = True
        ordering = ('-created_at',)# blog post categoryclass Category(CommonInfo):
    name = models.CharField(max_length=255)def __str__(self):return self.name# blog post instanceclass Post(CommonInfo):
    title = models.CharField(max_length=255)
    category = models.ForeignKey(Category,related_name='posts',on_delete=models.PROTECT)
    author = models.ForeignKey(User,related_name='posts',on_delete=models.PROTECT)
    content = models.TextField()
    published = models.BooleanField(default=False)def __str__(self):return f'{self.title} by {self.author.get_full_name()}'

對于此示例,我們將從命令行創建博客帖子的實例。腳本名為create_post.py

import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'commands.settings')import django
django.setup()from django.contrib.auth import get_user_modelfrom posts.models import Category, Post

User = get_user_model()def select_category():# retrieve categories. (You can create some examples from the django admin)categories = Category.objects.all().order_by('created_at')print('Please select a category for your post: ')for category in categories:print(f'{category.id}: {category}')
    category_id = input()
    category = Category.objects.get(id=category_id)return categorydef select_author():# retrieve all usersusers = User.objects.all()print('Please select an author for your post: ')for user in users:print(f'{user.id}: {user}')
    user_id = input()
    user = User.objects.get(id=user_id)return userdef create_post():
    title = input("Title of your post: ")
    content = input("Long post content: ")
    category = select_category()
    author = select_author()
    Post(**locals()).save()print('Post created successfully!')if __name__ == "__main__":
    create_post()

在這里,我們正在創建博客帖子的實例。請注意我們要如何處理ForeignKey關系?其實就是確保將相關數據庫表的對象實例分配給該字段。

通過運行python create_post.py,然后提示我們進行一些輸入。

編寫自定義django管理命令方法
文章剛看開始也提到了,django-admin命令是通過運行python manage.py command_name來執行的,我們平時用的有runserver,migrate和collectstatic。如果要獲取可用命令的列表,可以運行python manage.py help。這將顯示可用命令以及它們所在的django app文件夾的列表。

要注冊自定義管理命令,需要在django應用程序文件夾中添加一個management \ commands目錄。在我們的例子中,它將位于posts \ management \ commands中。

設置完成后,我們便可以在命令文件夾中初始化自定義腳本。對于第一個示例,我們將編寫一個命令,將之前創建的博客文章標記為已發布。

請創建一個文件并將其命名為publish_post.py

from django.core.management.base import BaseCommand, CommandErrorfrom posts.models import Category, Postclass Command(BaseCommand):
    help = 'Marks the specified blog post as published.'# allows for command line argsdef add_arguments(self, parser):
        parser.add_argument('post_id', type=int)def handle(self, *args, **options):try:
            post = Post.objects.get(id=options['post_id'])except Post.DoesNotExist:raise CommandError(f'Post with id {options["post_id"]} does not exist')if post.published:
            self.stdout.write(self.style.ERROR(f'Post: {post.title} was already published'))else:
            post.published = True
            post.save()
            self.stdout.write(self.style.SUCCESS(f'Post: {post.title} successfully published'))

Django管理命令由一個名為Command的類組成,該類繼承自BaseCommand。

為了接收參數,該類利用argparse。方法add_arguments允許我們的函數接收參數。

在我們的例子中,該函數期望一個參數,該參數將被分配鍵post_id

然后,handle()函數評估輸入并執行我們的邏輯。

在上面的示例中,期望的參數類型稱為位置參數,必須提供該參數才能運行該函數。為此,我們運行python manage.py publish_post 1(或任何發布主鍵)

顧名思義,可以將另一種類型的參數稱為可選參數應用于方法,缺少這些參數不會影響函數的執行。

下面提供了一個示例。我們將初始化一個文件并將其命名為edit_post.py。代碼如下:

from django.core.management.base import BaseCommand, CommandErrorfrom posts.models import Category, Postclass Command(BaseCommand):
    help = 'Edits the specified blog post.'def add_arguments(self, parser):
        parser.add_argument('post_id', type=int)# optional argumentsparser.add_argument('-t', '--title',type=str, help='Indicate new name of the blog post.')
        parser.add_argument('-c', '--content',type=str, help='Indicate new blog post content.')def handle(self, *args, **options):
        title = options['title']
        content = options['content']try:
            post = Post.objects.get(id=options['post_id'])except Post.DoesNotExist:raise CommandError(f'Post with id {options["post_id"]} does not exist')if title or content:if title:
                old_title = post.title
                post.title = title
                post.save()
                self.stdout.write(self.style.SUCCESS(f'Post: {old_title} has been update with a new title, {post.title}'))if content:
                post.content = content
                post.save()
                self.stdout.write(self.style.SUCCESS('Post: has been update with new text content.'))else:
            self.stdout.write(self.style.NOTICE('Post content remains the same as no arguments were given.'))

在這里,我們只是在編輯博客文章標題或內容。所以我們可以運行python manage.py edit_post 2 -t“ new title”僅編輯標題

或python manage.py edit_post -c “new content ”僅編輯內容。如果我們希望通過`python manage.py edit_post 2 -t “new title again” -c “new title again”編輯標題和內容,則可以提供兩個參數。

以上是“Django中怎么創建自定義命令”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

庄浪县| 北海市| 东海县| 长春市| 辽阳县| 旺苍县| 嘉定区| 广安市| 长丰县| 哈密市| 临朐县| 哈尔滨市| 牟定县| 满洲里市| 宁德市| 武宣县| 石棉县| 泽库县| 八宿县| 岚皋县| 简阳市| 通海县| 宜宾县| 汉寿县| 津市市| 石狮市| 阳城县| 勐海县| 农安县| 六盘水市| 德庆县| 凤台县| 马关县| 绍兴市| 时尚| 资溪县| 礼泉县| 高碑店市| 新安县| 正安县| 改则县|