在Django中保存任何文件时触发my函数

fnatzsnv  于 2023-08-08  发布在  Go
关注(0)|答案(2)|浏览(91)

我想点击Django应用程序中的文件保存事件

dockerized Django应用程序当我在任何文件中按下保存时,服务器将重新启动并重建docker镜像。
我喜欢类似的功能:每当我按下保存在任何文件,我希望我的函数被调用后,服务器重新启动。
如何实现这种行为。
我尝试覆盖FileSystemStorage,但它不工作。

from django.core.files.storage import FileSystemStorage
    

class CustomFileSystemStorage(FileSystemStorage):
    def _save(self, name, content):
        saved_file_name = super()._save(name, content)
        self.my_custom_function(saved_file_name, name, content)
    
        return saved_file_name

    def my_custom_function(self, file_path, name, content):
        print('File saved at: ', file_path)
        print('File name: ', name)
        print('File content: ', content)

字符串
settings.py

DEFAULT_FILE_STORAGE = 'myApp.storage.CustomFileSystemStorage'


当我保存文件时,没有记录任何内容

不是解决方案:

  • 以编程方式保存文件时触发
  • 保存模型对象时触发

编辑:

press save on ant file的意思是在我正在编辑的文件上按cmd+s(例如:test.py
磁盘上的任何更改都会导致重新构建docker镜像。我想做类似他们所做的。

编辑二:

我认为,因为在保存服务器重新启动和Docker镜像重建...也许有办法触动那些触发器
服务器重启时可以触发我的函数吗?但要找到一个被修改过的文件可能很难...

编辑3:

我的apps.py

from django.apps import AppConfig
import logging

class MyAppConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'myApp'

    def ready(self):
        logger = logging.getLogger(__name__)
        logger.info("READY 123123")


我也试试

from django.apps import AppConfig
import logging

class MyAppConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'myApp'

    def ready(self):
        print('TEST')


settings.py

"""
Django settings for WisdomCore project.

Generated by 'django-admin startproject' using Django 4.2.

For more information on this file, see
https://docs.djangoproject.com/en/4.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""

from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'xxx'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'my_app'
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'Projects.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'Project.wsgi.application'

# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/

STATIC_URL = 'static/'

# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django': {
            'level': 'INFO',
            'handlers': ['console'],
            'propagate': True,
        },
        'django.db.backends': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': True,
        }
    },
}


日志包括:


的数据
我没有别的密码了...
我的树

├── Dockerfile
├── Project
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── docker-compose.yml
├── my_app
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── install.sh
├── local_settings.py
├── makefile
├── manage.py
├── neo4j-conf
│   └── neo4j.conf
├── neo4j_data
└── requirements.txt

2mbi3lxu

2mbi3lxu1#


每当我按下保存在任何文件,我希望我的函数被调用后,服务器重新启动。
这就是你想要的,没有更多的,你可以添加到你的应用程序配置文件

from django.apps import AppConfig
class MyAppConfig(AppConfig):
    name = 'myapp'
    verbose_name = "My Application"
    def ready(self):
        pass # Put your function code here

字符串
这将在你的django应用程序启动时运行,只有一次,因为当你保存一个文件时,服务器会重新启动并重建docker镜像,它会按照你的要求运行。

8nuwlpux

8nuwlpux2#

谢谢你们所有人的建议,让我找到了正确的答案。

检测服务器重启

类似于@ David的建议,我通过AppConfig解决了这个问题
1.创建包含要运行的代码的管理命令

# commands/startup_actions.py
from django.core.management.base import BaseCommand

class Command(BaseCommand):
    help = 'Actions to perform on server startup or app ready'

    def handle(self, *args, **options):
        # Put your startup actions here, similar to what you would have done in AppConfig.ready
        print("Server is starting up or app is ready.")

字符串
1.在AppConfig中调用此方法:

from django.apps import AppConfig

class MyAppConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'myApp'

    def ready(self):
        # Run the custom management command on server startup
        from django.core.management import call_command
        call_command('startup_actions')


这实际上工作并在文件保存时打印“服务器正在启动或应用程序准备就绪。”

但是:您需要自己找出哪个文件发生了更改。

检测文件变化

您可以使用看门狗库来检测哪个文件被更改了

  1. Pip安装看门狗:
pip install watchdog==3.0.0


我也把它放在requirement.txt里面
1.在root目录中创建file_observer.py文件

# file_observer.py

import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler, RegexMatchingEventHandler

from graph_parser.parser import CypherMethodParser

class MyHandler(RegexMatchingEventHandler):
    def on_modified(self, event):
        if event.is_directory:
            return
        # This function will be called when a file is modified
        print(f"File {event.src_path} has been modified with {event} event.")
        # Sometimes this is called 2 times in a row. To prevent this put sleep
        time.sleep(1)

def start_observer():
    event_handler = MyHandler(regexes=[r'.*\.py$', r'.*\.csv$'])
    observer = Observer()
    observer.schedule(event_handler, path='.', recursive=True)
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

if __name__ == "__main__":
    start_observer()


1.在install.sh中(或者在docker容器中安装requirements.txt的地方...)添加

pip install --upgrade pip
pip install -r requirements.txt
python file_observer.py &        # <--- this is the new line

相关问题