📜  自定义 Django 管理命令

📅  最后修改于: 2022-05-13 01:55:36.963000             🧑  作者: Mango

自定义 Django 管理命令

先决条件: Django 介绍和安装

Django 中的 Manage.py 是一个命令行实用程序,其工作方式类似于 django-admin 命令。不同之处在于它指向项目的 settings.py 文件。这个 manage.py 实用程序提供了使用 Django 时必须使用的各种命令。一些最常用的命令是——

  • Python manage.py startapp
  • Python manage.py makemigrations
  • Python manage.py 迁移
  • Python manage.py runserver

有趣的是,我们可以创建我们自己的自定义管理命令来满足各种各样的需求,从使用命令行与我们的应用程序交互到作为执行 Cron 作业的接口。我们将创建一个自定义管理命令,它为我们提供新文章发布的统计信息或指标,以及特定日期对这些文章的评论。

入门

按照 Django 介绍和安装来设置虚拟环境并安装 Django

第 1 步:初始化 通过以下命令创建一个项目



django-admin startproject geeks_site

第 2 步:创建一个名为 blog 的应用程序

python manage.py startapp blog

第 3 步:将您的应用添加到 settings.py

geeks_site/settings.py

Python3
# Application definition
  
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
      'blog',
]


Python3
from django.db import models
  
  
class Article(models.Model):
    title = models.CharField(max_length=200)
    body = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
  
  
class Comment(models.Model):
    article = models.ForeignKey(Article, on_delete=models.CASCADE)
    text = models.CharField(max_length=200)
    created_on = models.DateTimeField(auto_now_add=True)


Python3
from django.contrib import admin 
from .models import Article, Comment
    
admin.site.register(Article)
admin.site.register(Comment)


Python3
from django.core.management.base import BaseCommand
from django.db.models import Count
from blog.models import Article, Comment
from datetime import timedelta, datetime
from django.utils.timezone import utc
  
  
def now():
    return datetime.utcnow().replace(tzinfo=utc)
  
  
class Command(BaseCommand):
    help = 'Displays stats related to Article and Comment models'
  
    def handle(self, *args, **kwargs):
        From = now() - timedelta(hours=5)
        To = now()
  
        articles_published_in_last_5_hour = Article.objects.filter(
            created_on__gt=From, created_on__lte=To).count()
        comments_published_per_article = Comment.objects.filter(
            created_on__gt=From, created_on__lte=To).values(
          'article').annotate(count=Count('article')).order_by()
  
        print("Articles Published in last 5 hours = ",
              articles_published_in_last_5_hour)
          
        print("Comments per Article in last 5 hours")
        for data in comments_published_per_article:
            print(data)


Python3
from django.core.management.base import BaseCommand
from django.db.models import Count
from app.models import Article, Comment
from datetime import timedelta, datetime
from django.utils.timezone import utc
  
  
def now():
    return datetime.utcnow().replace(tzinfo=utc)
  
class Command(BaseCommand):
    help = 'Displays stats related to Article and Comment models'
  
    def add_arguments(self, parser):
        parser.add_argument('-t', '--time', type=int, help='Articles published in last t hours')
  
    def handle(self, *args, **kwargs):
        t = kwargs['time']
        if not t:
            t=5
        From = now() - timedelta(hours=t)
        To = now()
  
        articles_published_in_last_t_hour = Article.objects.filter(
            created_on__gt=From, created_on__lte=To).count()
          
        comments_published_per_article = Comment.objects.filter(
            created_on__gt=From, created_on__lte=To).values(
            'article').annotate(count=Count('article')).order_by()
  
        print(f"Articles Published in last {t} hours = ",
              articles_published_in_last_t_hour)
  
        print(f"Comments per Article in last {t} hours")
        for data in comments_published_per_article:
            print(data)


第 4 步:博客应用程序中创建名为文章评论的模型

模型文章

  • 领域
    • title : 存储文章的标题
    • body : 那篇文章的内容
    • created_on :该文章的创建日期和时间

型号评论

  • 领域
    • article : 创建评论的文章
    • text : 实际评论
    • created_on :该文章的创建日期和时间

博客/models.py



蟒蛇3

from django.db import models
  
  
class Article(models.Model):
    title = models.CharField(max_length=200)
    body = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
  
  
class Comment(models.Model):
    article = models.ForeignKey(Article, on_delete=models.CASCADE)
    text = models.CharField(max_length=200)
    created_on = models.DateTimeField(auto_now_add=True)

第 5 步:在 blog/admin.py 中注册您的模型,以便它显示在管理面板中。

博客/admin.py

蟒蛇3

from django.contrib import admin 
from .models import Article, Comment
    
admin.site.register(Article)
admin.site.register(Comment)

第 6 步:现在,要迁移所有更改并启动服务器,请在终端中运行以下命令

python manage.py makemigrations
python manage.py migrate
python manage.py runserver

创建一个超级用户帐户以登录管理面板

python manage.py createsuperuser

现在,访问管理面板 http://127.0.0.1:8000/admin/

创建一些文章,然后发表一些评论:



现在,让我们开始创建自定义 Django 管理命令

  • 管理/命令目录添加到博客应用程序
  • __init__.py添加到blog/management并将__init__.py + stats.py文件添加到blog/management/commands目录

注意: Django 将为该目录中名称不以下划线开头的每个Python模块注册一个manage.py命令

博客应用程序的文件夹结构如下所示:

我们将使用Python manage.py stats来运行我们的自定义管理命令。现在我们将配置这个命令的实际作用。

stats.py 中

蟒蛇3

from django.core.management.base import BaseCommand
from django.db.models import Count
from blog.models import Article, Comment
from datetime import timedelta, datetime
from django.utils.timezone import utc
  
  
def now():
    return datetime.utcnow().replace(tzinfo=utc)
  
  
class Command(BaseCommand):
    help = 'Displays stats related to Article and Comment models'
  
    def handle(self, *args, **kwargs):
        From = now() - timedelta(hours=5)
        To = now()
  
        articles_published_in_last_5_hour = Article.objects.filter(
            created_on__gt=From, created_on__lte=To).count()
        comments_published_per_article = Comment.objects.filter(
            created_on__gt=From, created_on__lte=To).values(
          'article').annotate(count=Count('article')).order_by()
  
        print("Articles Published in last 5 hours = ",
              articles_published_in_last_5_hour)
          
        print("Comments per Article in last 5 hours")
        for data in comments_published_per_article:
            print(data)

了解 stats.py 文件

基本上,Django 管理命令是从一个名为Command的类构建的,该类继承自BaseCommand

1) 帮助:它说明命令的实际作用。运行以下命令,查看帮助



python manage.py stats --help

2)handle():处理命令执行时需要执行的所有逻辑。让我们了解一下handle()方法中的代码

  • 这里我们关注以下两个统计数据
    • 最近 5 小时内发表的文章数
    • 每篇文章在过去 5 小时内创建的评论数
  • 从:当前时间 – 5 小时
  • 至:当前时间
  • Articles_published_in_last_5_hour :一个整数值
  • comments_published_per_article :查询集对象或字典列表
  • 打印语句以在终端上输出数据

现在,在终端中运行以下命令:

python manage.py stats

输出 :

添加参数

Django 使用 argparse 模块来处理自定义参数。我们需要在命令类下定义一个函数add_arguments 来处理参数。

蟒蛇3

from django.core.management.base import BaseCommand
from django.db.models import Count
from app.models import Article, Comment
from datetime import timedelta, datetime
from django.utils.timezone import utc
  
  
def now():
    return datetime.utcnow().replace(tzinfo=utc)
  
class Command(BaseCommand):
    help = 'Displays stats related to Article and Comment models'
  
    def add_arguments(self, parser):
        parser.add_argument('-t', '--time', type=int, help='Articles published in last t hours')
  
    def handle(self, *args, **kwargs):
        t = kwargs['time']
        if not t:
            t=5
        From = now() - timedelta(hours=t)
        To = now()
  
        articles_published_in_last_t_hour = Article.objects.filter(
            created_on__gt=From, created_on__lte=To).count()
          
        comments_published_per_article = Comment.objects.filter(
            created_on__gt=From, created_on__lte=To).values(
            'article').annotate(count=Count('article')).order_by()
  
        print(f"Articles Published in last {t} hours = ",
              articles_published_in_last_t_hour)
  
        print(f"Comments per Article in last {t} hours")
        for data in comments_published_per_article:
            print(data)

输出: