diff --git a/README.md b/README.md index e69de29..be6dc33 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,3 @@ +## 新版阅马共读后端 + +新版阅马共读后端使用 Python+Django+DRF 代替 SpringBoot 和 Quester 中的功能。迁移可能会持续很长时间。访问请求大部分时候由 Django 转发到 Spring 以及 Quester 中,逐步迁移所有接口。新功能在 Django 端做。 diff --git a/poetry.lock b/poetry.lock index 3d66d11..ab1fac9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,24 @@ # This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +[[package]] +name = "amqp" +version = "5.2.0" +description = "Low-level AMQP client for Python (fork of amqplib)." +optional = false +python-versions = ">=3.6" +files = [ + {file = "amqp-5.2.0-py3-none-any.whl", hash = "sha256:827cb12fb0baa892aad844fd95258143bce4027fdac4fccddbc43330fd281637"}, + {file = "amqp-5.2.0.tar.gz", hash = "sha256:a1ecff425ad063ad42a486c902807d1482311481c8ad95a72694b2975e75f7fd"}, +] + +[package.dependencies] +vine = ">=5.0.0,<6.0.0" + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + [[package]] name = "asgiref" version = "3.8.1" @@ -19,6 +38,83 @@ type = "legacy" url = "http://mirrors.aliyun.com/pypi/simple" reference = "aliyun" +[[package]] +name = "billiard" +version = "4.2.0" +description = "Python multiprocessing fork with improvements and bugfixes" +optional = false +python-versions = ">=3.7" +files = [ + {file = "billiard-4.2.0-py3-none-any.whl", hash = "sha256:07aa978b308f334ff8282bd4a746e681b3513db5c9a514cbdd810cbbdc19714d"}, + {file = "billiard-4.2.0.tar.gz", hash = "sha256:9a3c3184cb275aa17a732f93f65b20c525d3d9f253722d26a82194803ade5a2c"}, +] + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + +[[package]] +name = "celery" +version = "5.3.6" +description = "Distributed Task Queue." +optional = false +python-versions = ">=3.8" +files = [ + {file = "celery-5.3.6-py3-none-any.whl", hash = "sha256:9da4ea0118d232ce97dff5ed4974587fb1c0ff5c10042eb15278487cdd27d1af"}, + {file = "celery-5.3.6.tar.gz", hash = "sha256:870cc71d737c0200c397290d730344cc991d13a057534353d124c9380267aab9"}, +] + +[package.dependencies] +billiard = ">=4.2.0,<5.0" +click = ">=8.1.2,<9.0" +click-didyoumean = ">=0.3.0" +click-plugins = ">=1.1.1" +click-repl = ">=0.2.0" +kombu = ">=5.3.4,<6.0" +python-dateutil = ">=2.8.2" +redis = {version = ">=4.5.2,<4.5.5 || >4.5.5,<6.0.0", optional = true, markers = "extra == \"redis\""} +tzdata = ">=2022.7" +vine = ">=5.1.0,<6.0" + +[package.extras] +arangodb = ["pyArango (>=2.0.2)"] +auth = ["cryptography (==41.0.5)"] +azureblockblob = ["azure-storage-blob (>=12.15.0)"] +brotli = ["brotli (>=1.0.0)", "brotlipy (>=0.7.0)"] +cassandra = ["cassandra-driver (>=3.25.0,<4)"] +consul = ["python-consul2 (==0.1.5)"] +cosmosdbsql = ["pydocumentdb (==2.3.5)"] +couchbase = ["couchbase (>=3.0.0)"] +couchdb = ["pycouchdb (==1.14.2)"] +django = ["Django (>=2.2.28)"] +dynamodb = ["boto3 (>=1.26.143)"] +elasticsearch = ["elastic-transport (<=8.10.0)", "elasticsearch (<=8.11.0)"] +eventlet = ["eventlet (>=0.32.0)"] +gevent = ["gevent (>=1.5.0)"] +librabbitmq = ["librabbitmq (>=2.0.0)"] +memcache = ["pylibmc (==1.6.3)"] +mongodb = ["pymongo[srv] (>=4.0.2)"] +msgpack = ["msgpack (==1.0.7)"] +pymemcache = ["python-memcached (==1.59)"] +pyro = ["pyro4 (==4.82)"] +pytest = ["pytest-celery (==0.0.0)"] +redis = ["redis (>=4.5.2,!=4.5.5,<6.0.0)"] +s3 = ["boto3 (>=1.26.143)"] +slmq = ["softlayer-messaging (>=1.0.3)"] +solar = ["ephem (==4.1.5)"] +sqlalchemy = ["sqlalchemy (>=1.4.48,<2.1)"] +sqs = ["boto3 (>=1.26.143)", "kombu[sqs] (>=5.3.0)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"] +tblib = ["tblib (>=1.3.0)", "tblib (>=1.5.0)"] +yaml = ["PyYAML (>=3.10)"] +zookeeper = ["kazoo (>=1.3.1)"] +zstd = ["zstandard (==0.22.0)"] + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + [[package]] name = "cfgv" version = "3.4.0" @@ -35,6 +131,124 @@ type = "legacy" url = "http://mirrors.aliyun.com/pypi/simple" reference = "aliyun" +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + +[[package]] +name = "click-didyoumean" +version = "0.3.1" +description = "Enables git-like *did-you-mean* feature in click" +optional = false +python-versions = ">=3.6.2" +files = [ + {file = "click_didyoumean-0.3.1-py3-none-any.whl", hash = "sha256:5c4bb6007cfea5f2fd6583a2fb6701a22a41eb98957e63d0fac41c10e7c3117c"}, + {file = "click_didyoumean-0.3.1.tar.gz", hash = "sha256:4f82fdff0dbe64ef8ab2279bd6aa3f6a99c3b28c05aa09cbfc07c9d7fbb5a463"}, +] + +[package.dependencies] +click = ">=7" + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + +[[package]] +name = "click-plugins" +version = "1.1.1" +description = "An extension module for click to enable registering CLI commands via setuptools entry-points." +optional = false +python-versions = "*" +files = [ + {file = "click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b"}, + {file = "click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8"}, +] + +[package.dependencies] +click = ">=4.0" + +[package.extras] +dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + +[[package]] +name = "click-repl" +version = "0.3.0" +description = "REPL plugin for Click" +optional = false +python-versions = ">=3.6" +files = [ + {file = "click-repl-0.3.0.tar.gz", hash = "sha256:17849c23dba3d667247dc4defe1757fff98694e90fe37474f3feebb69ced26a9"}, + {file = "click_repl-0.3.0-py3-none-any.whl", hash = "sha256:fb7e06deb8da8de86180a33a9da97ac316751c094c6899382da7feeeeb51b812"}, +] + +[package.dependencies] +click = ">=7.0" +prompt-toolkit = ">=3.0.36" + +[package.extras] +testing = ["pytest (>=7.2.1)", "pytest-cov (>=4.0.0)", "tox (>=4.4.3)"] + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + +[[package]] +name = "cron-descriptor" +version = "1.4.3" +description = "A Python library that converts cron expressions into human readable strings." +optional = false +python-versions = "*" +files = [ + {file = "cron_descriptor-1.4.3-py3-none-any.whl", hash = "sha256:a67ba21804983b1427ed7f3e1ec27ee77bf24c652b0430239c268c5ddfbf9dc0"}, + {file = "cron_descriptor-1.4.3.tar.gz", hash = "sha256:7b1a00d7d25d6ae6896c0da4457e790b98cba778398a3d48e341e5e0d33f0488"}, +] + +[package.extras] +dev = ["polib"] + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + [[package]] name = "distlib" version = "0.3.8" @@ -128,6 +342,68 @@ type = "legacy" url = "http://mirrors.aliyun.com/pypi/simple" reference = "aliyun" +[[package]] +name = "django-celery-beat" +version = "2.6.0" +description = "Database-backed Periodic Tasks." +optional = false +python-versions = "*" +files = [ + {file = "django-celery-beat-2.6.0.tar.gz", hash = "sha256:f75b2d129731f1214be8383e18fae6bfeacdb55dffb2116ce849222c0106f9ad"}, +] + +[package.dependencies] +celery = ">=5.2.3,<6.0" +cron-descriptor = ">=1.2.32" +Django = ">=2.2,<5.1" +django-timezone-field = ">=5.0" +python-crontab = ">=2.3.4" +tzdata = "*" + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + +[[package]] +name = "django-celery-results" +version = "2.5.1" +description = "Celery result backends for Django." +optional = false +python-versions = "*" +files = [ + {file = "django_celery_results-2.5.1-py3-none-any.whl", hash = "sha256:0da4cd5ecc049333e4524a23fcfc3460dfae91aa0a60f1fae4b6b2889c254e01"}, + {file = "django_celery_results-2.5.1.tar.gz", hash = "sha256:3ecb7147f773f34d0381bac6246337ce4cf88a2ea7b82774ed48e518b67bb8fd"}, +] + +[package.dependencies] +celery = ">=5.2.7,<6.0" +Django = ">=3.2.18" + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + +[[package]] +name = "django-timezone-field" +version = "6.1.0" +description = "A Django app providing DB, form, and REST framework fields for zoneinfo and pytz timezone objects." +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "django_timezone_field-6.1.0-py3-none-any.whl", hash = "sha256:0095f43da716552fcc606783cfb42cb025892514f1ec660ebfa96186eb83b74c"}, + {file = "django_timezone_field-6.1.0.tar.gz", hash = "sha256:d40f7059d7bae4075725d04a9dae601af9fe3c7f0119a69b0e2c6194a782f797"}, +] + +[package.dependencies] +Django = ">=3.2,<6.0" + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + [[package]] name = "djangorestframework" version = "3.15.1" @@ -231,6 +507,43 @@ type = "legacy" url = "http://mirrors.aliyun.com/pypi/simple" reference = "aliyun" +[[package]] +name = "kombu" +version = "5.3.7" +description = "Messaging library for Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "kombu-5.3.7-py3-none-any.whl", hash = "sha256:5634c511926309c7f9789f1433e9ed402616b56836ef9878f01bd59267b4c7a9"}, + {file = "kombu-5.3.7.tar.gz", hash = "sha256:011c4cd9a355c14a1de8d35d257314a1d2456d52b7140388561acac3cf1a97bf"}, +] + +[package.dependencies] +amqp = ">=5.1.1,<6.0.0" +vine = "*" + +[package.extras] +azureservicebus = ["azure-servicebus (>=7.10.0)"] +azurestoragequeues = ["azure-identity (>=1.12.0)", "azure-storage-queue (>=12.6.0)"] +confluentkafka = ["confluent-kafka (>=2.2.0)"] +consul = ["python-consul2"] +librabbitmq = ["librabbitmq (>=2.0.0)"] +mongodb = ["pymongo (>=4.1.1)"] +msgpack = ["msgpack"] +pyro = ["pyro4"] +qpid = ["qpid-python (>=0.26)", "qpid-tools (>=0.26)"] +redis = ["redis (>=4.5.2,!=4.5.5,!=5.0.2)"] +slmq = ["softlayer-messaging (>=1.0.3)"] +sqlalchemy = ["sqlalchemy (>=1.4.48,<2.1)"] +sqs = ["boto3 (>=1.26.143)", "pycurl (>=7.43.0.5)", "urllib3 (>=1.26.16)"] +yaml = ["PyYAML (>=3.10)"] +zookeeper = ["kazoo (>=2.8.0)"] + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + [[package]] name = "marshmallow" version = "3.21.1" @@ -356,6 +669,67 @@ type = "legacy" url = "http://mirrors.aliyun.com/pypi/simple" reference = "aliyun" +[[package]] +name = "prompt-toolkit" +version = "3.0.43" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"}, + {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"}, +] + +[package.dependencies] +wcwidth = "*" + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + +[[package]] +name = "python-crontab" +version = "3.0.0" +description = "Python Crontab API" +optional = false +python-versions = "*" +files = [ + {file = "python-crontab-3.0.0.tar.gz", hash = "sha256:79fb7465039ddfd4fb93d072d6ee0d45c1ac8bf1597f0686ea14fd4361dba379"}, + {file = "python_crontab-3.0.0-py3-none-any.whl", hash = "sha256:6d5ba3c190ec76e4d252989a1644fcb233dbf53fbc8fceeb9febe1657b9fb1d4"}, +] + +[package.dependencies] +python-dateutil = "*" + +[package.extras] +cron-description = ["cron-descriptor"] +cron-schedule = ["croniter"] + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + [[package]] name = "python-dotenv" version = "1.0.1" @@ -440,6 +814,26 @@ type = "legacy" url = "http://mirrors.aliyun.com/pypi/simple" reference = "aliyun" +[[package]] +name = "redis" +version = "5.0.3" +description = "Python client for Redis database and key-value store" +optional = false +python-versions = ">=3.7" +files = [ + {file = "redis-5.0.3-py3-none-any.whl", hash = "sha256:5da9b8fe9e1254293756c16c008e8620b3d15fcc6dde6babde9541850e72a32d"}, + {file = "redis-5.0.3.tar.gz", hash = "sha256:4973bae7444c0fbed64a06b87446f79361cb7e4ec1538c022d696ed7a5015580"}, +] + +[package.extras] +hiredis = ["hiredis (>=1.0.0)"] +ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"] + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + [[package]] name = "ruff" version = "0.3.7" @@ -492,6 +886,22 @@ type = "legacy" url = "http://mirrors.aliyun.com/pypi/simple" reference = "aliyun" +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + [[package]] name = "sqlparse" version = "0.5.0" @@ -544,6 +954,22 @@ type = "legacy" url = "http://mirrors.aliyun.com/pypi/simple" reference = "aliyun" +[[package]] +name = "vine" +version = "5.1.0" +description = "Python promises." +optional = false +python-versions = ">=3.6" +files = [ + {file = "vine-5.1.0-py3-none-any.whl", hash = "sha256:40fdf3c48b2cfe1c38a49e9ae2da6fda88e4794c810050a728bd7413811fb1dc"}, + {file = "vine-5.1.0.tar.gz", hash = "sha256:8b62e981d35c41049211cf62a0a1242d8c1ee9bd15bb196ce38aefd6799e61e0"}, +] + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + [[package]] name = "virtualenv" version = "20.25.1" @@ -569,7 +995,23 @@ type = "legacy" url = "http://mirrors.aliyun.com/pypi/simple" reference = "aliyun" +[[package]] +name = "wcwidth" +version = "0.2.13" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] + +[package.source] +type = "legacy" +url = "http://mirrors.aliyun.com/pypi/simple" +reference = "aliyun" + [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "3f835998771824a76656d128647cff83ed1863c255eeb60092fbb3b44e62b90b" +content-hash = "ddd2dd0a6ba2473bd52e4d62c4ab04b3e404a0984654a14d845a147cd3e5cbc4" diff --git a/pyproject.toml b/pyproject.toml index 890b46d..457ae95 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,9 @@ django = "^5.0.4" djangorestframework = "^3.15.1" environs = { version = "^11.0.0", extras = ["django"] } mysqlclient = "^2.2.4" +celery = {version = "^5.3.6", extras = ["redis"]} +django-celery-results = "^2.5.1" +django-celery-beat = "^2.6.0" [[tool.poetry.source]] diff --git a/src/premier/__init__.py b/src/premier/__init__.py index e69de29..53f4ccb 100644 --- a/src/premier/__init__.py +++ b/src/premier/__init__.py @@ -0,0 +1,3 @@ +from .celery import app as celery_app + +__all__ = ("celery_app",) diff --git a/src/premier/celery.py b/src/premier/celery.py new file mode 100644 index 0000000..6d9d7fe --- /dev/null +++ b/src/premier/celery.py @@ -0,0 +1,22 @@ +import os + +from celery import Celery + +# Set the default Django settings module for the 'celery' program. +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "premier.settings") + +app = Celery("premier") + +# Using a string here means the worker doesn't have to serialize +# the configuration object to child processes. +# - namespace='CELERY' means all celery-related configuration keys +# should have a `CELERY_` prefix. +app.config_from_object("django.conf:settings", namespace="CELERY") + +# Load task modules from all registered Django apps. +app.autodiscover_tasks() + + +@app.task(bind=True, ignore_result=True) +def debug_task(self): + print(f"Request: {self.request!r}") diff --git a/src/premier/origin/models.py b/src/premier/origin/models.py index 0947f73..2cb6a5f 100644 --- a/src/premier/origin/models.py +++ b/src/premier/origin/models.py @@ -2693,65 +2693,6 @@ class User(models.Model): db_table = "user" -class User210414(models.Model): - id = models.BigIntegerField(db_comment="主键") - createdby = models.BigIntegerField( - db_column="createdBy", db_comment="创建人" - ) # Field name made lowercase. - createdtime = models.DateTimeField( - db_column="createdTime", db_comment="创建时间" - ) # Field name made lowercase. - delflag = models.IntegerField( - db_column="delFlag", db_comment="软删除标志,0未删除,1已删除" - ) # Field name made lowercase. - lastupdate = models.DateTimeField( - db_column="lastUpdate", db_comment="最后更新时间" - ) # Field name made lowercase. - sortno = models.IntegerField( - db_column="sortNo", db_comment="排序号,默认0" - ) # Field name made lowercase. - updatedby = models.BigIntegerField( - db_column="updatedBy", blank=True, null=True, db_comment="更新人" - ) # Field name made lowercase. - updatedtime = models.DateTimeField( - db_column="updatedTime", blank=True, null=True, db_comment="更新时间" - ) # Field name made lowercase. - version = models.IntegerField(db_comment="乐观锁,默认0") - avatar = models.CharField(max_length=255, blank=True, null=True) - datascope = models.CharField( - db_column="dataScope", max_length=50, blank=True, null=True - ) # Field name made lowercase. - email = models.CharField(max_length=255, blank=True, null=True) - forbiddenflag = models.CharField( - db_column="forbiddenFlag", max_length=50, blank=True, null=True - ) # Field name made lowercase. - gender = models.CharField(max_length=50, blank=True, null=True) - loginname = models.CharField( - db_column="loginName", max_length=255, blank=True, null=True - ) # Field name made lowercase. - mobile = models.CharField(max_length=255, blank=True, null=True) - nickname = models.CharField(max_length=255, blank=True, null=True) - orgid = models.BigIntegerField( - db_column="orgId", blank=True, null=True - ) # Field name made lowercase. - password = models.CharField(max_length=255, blank=True, null=True) - realname = models.CharField( - db_column="realName", max_length=255, blank=True, null=True - ) # Field name made lowercase. - remark = models.CharField(max_length=255, blank=True, null=True) - userstatus = models.CharField( - db_column="userStatus", max_length=50, blank=True, null=True - ) # Field name made lowercase. - usertype = models.CharField( - db_column="userType", max_length=50, blank=True, null=True - ) # Field name made lowercase. - username = models.CharField(max_length=255, blank=True, null=True) - - class Meta: - managed = False - db_table = "user_210414" - - class UserFollow(models.Model): id = models.BigAutoField(primary_key=True, db_comment="主键") createdby = models.BigIntegerField( diff --git a/src/premier/settings.py b/src/premier/settings.py index 853a3ae..54a5ae3 100644 --- a/src/premier/settings.py +++ b/src/premier/settings.py @@ -43,6 +43,8 @@ INSTALLED_APPS = [ "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", + "django_celery_results", + "django_celery_beat", ] MIDDLEWARE = [ @@ -122,3 +124,14 @@ STATIC_URL = "static/" # https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" + + +# Celery + +CELERY_BROKER_URL = env.str("CELERY_BROKER_URL") +CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True +CELERY_TIMEZONE = "Asia/Shanghai" +CELERY_TASK_TIME_LIMIT = 30 * 60 +CELERY_RESULT_BACKEND = "django-db" +CELERY_CACHE_BACKEND = "django-cache" +CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler" diff --git a/tasks.py b/tasks.py index 3e3010e..98f1cd0 100644 --- a/tasks.py +++ b/tasks.py @@ -1,4 +1,5 @@ from invoke import task +from threading import Thread @task @@ -6,6 +7,11 @@ def dev(c): c.run("manage runserver", pty=True) +@task +def celery(c): + c.run("celery -A premier worker -l INFO -c 2 -P prefork -B", pty=True) + + @task def style(c): c.run("ruff check . --fix && ruff format .", pty=True)