{"id":20619741,"url":"https://github.com/twtrubiks/docker-django-celery-tutorial","last_synced_at":"2025-04-15T12:02:29.683Z","repository":{"id":37406255,"uuid":"123796645","full_name":"twtrubiks/docker-django-celery-tutorial","owner":"twtrubiks","description":" docker-django-celery-tutorial 基本教學  📝","archived":false,"fork":false,"pushed_at":"2022-06-27T12:08:59.000Z","size":53,"stargazers_count":51,"open_issues_count":2,"forks_count":10,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-28T19:53:44.370Z","etag":null,"topics":["celery","django","docker","rabbitmq","tutorial"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/twtrubiks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-03-04T14:28:47.000Z","updated_at":"2025-02-17T23:31:42.000Z","dependencies_parsed_at":"2022-09-09T02:10:47.899Z","dependency_job_id":null,"html_url":"https://github.com/twtrubiks/docker-django-celery-tutorial","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twtrubiks%2Fdocker-django-celery-tutorial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twtrubiks%2Fdocker-django-celery-tutorial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twtrubiks%2Fdocker-django-celery-tutorial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twtrubiks%2Fdocker-django-celery-tutorial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/twtrubiks","download_url":"https://codeload.github.com/twtrubiks/docker-django-celery-tutorial/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249067779,"owners_count":21207395,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["celery","django","docker","rabbitmq","tutorial"],"created_at":"2024-11-16T12:12:23.815Z","updated_at":"2025-04-15T12:02:29.652Z","avatar_url":"https://github.com/twtrubiks.png","language":"Python","readme":"# docker-django-celery-tutorial\n\n docker-django-celery-tutorial 基本教學  📝\n\n* [Youtube Tutorial Part1 - Docker 安裝 RabbitMQ](https://youtu.be/W4ktp3EjFXY)\n\n* [Youtube Tutorial Part2 - Python 結合 Celery ( 使用 Docker )](https://youtu.be/B8Qq9KxEjZc)\n\n* [Youtube Tutorial Part3 - 實戰 Django + Celery ( 使用 Docker )](https://youtu.be/3dwRrJml2NQ)\n\n之前其實也寫過相關的教學，可參考 [django-celery-tutorial](https://github.com/twtrubiks/django-celery-tutorial#django-celery-tutorial)，\n\n那這邊為什麼還要再寫一篇文章介紹呢:question::question::question:\n\n是因為接觸 docker 後，發現 docker 的好，不懂 docker 是什麼？\n\n請參考 [docker-tutorial](https://github.com/twtrubiks/docker-tutorial):laughing:\n\n所以這篇教大家用 docker 建立 Celery，如果你看過 [這篇](https://github.com/twtrubiks/django-celery-tutorial#broker-tutorial) 的介紹，\n\n你會發現安裝環境很麻煩，尤其是在 Windows 上,\n\n所以這篇會全部使用 docker 來完成:smirk:\n\n## 前言\n\n這邊一些為什麼 Celery 要用 RabbitMQ 的問題就不再做介紹，詳細介紹\n\n可參考 [django-celery-tutorial](https://github.com/twtrubiks/django-celery-tutorial):blush:\n\n透過這篇文章，你將會學會\n\n* [Docker 安裝 RabbitMQ](https://github.com/twtrubiks/docker-django-celery-tutorial#docker-%E5%AE%89%E8%A3%9D-rabbitmq)\n* [Python 結合 Celery ( 使用 Docker )](https://github.com/twtrubiks/docker-django-celery-tutorial#python-%E7%B5%90%E5%90%88-celery)\n* [實戰 Django + Celery ( 使用 Docker )](https://github.com/twtrubiks/docker-django-celery-tutorial#%E5%AF%A6%E6%88%B0-django--celery)\n\n## Docker 安裝 RabbitMQ\n\n* [Youtube Tutorial Part1 - Docker 安裝 RabbitMQ](https://youtu.be/W4ktp3EjFXY)\n\n詳細教學可參考 [Docker RabbitMQ](https://hub.docker.com/_/rabbitmq/) ，請直接執行下列的指令，\n\n```cmd\ndocker run -d --hostname my-rabbit --name some-rabbit -e RABBITMQ_DEFAULT_USER=celery -e RABBITMQ_DEFAULT_PASS=password123  -e RABBITMQ_DEFAULT_VHOST=my_vhost -p 5672:5672 -p 15672:15672 rabbitmq:3.10.5-management\n```\n\n比較特別的是，`RABBITMQ_DEFAULT_VHOST` 這個東西，如果大家有興趣，可以 google **RabbitMQ virtual hosts**\n\n進一步的去了解 :grinning:（ 或是有機會我有研究會再補上來 ）\n\n可直接瀏覽 [http://0.0.0.0:15672/](http://0.0.0.0:15672/)\n\n![alt tag](https://i.imgur.com/kunrVdl.png)\n\n輸入你的帳密後，應該可以看到類似的畫面\n\n![alt tag](https://i.imgur.com/C4sTKad.png)\n\n接下來，我將介紹如何將 Celery 結合 Python :satisfied:\n\n## Python 結合 Celery\n\n建議搭配影片看比較好理解 :blush:\n\n* [Youtube Tutorial Part2 - Python 結合 Celery ( 使用 Docker )](https://youtu.be/B8Qq9KxEjZc)\n\n### Celery\n\nPython 結合 Celery，可參考 [celery-demo](https://github.com/twtrubiks/docker-django-celery-tutorial/tree/master/celery-demo)，這邊要注意兩點，\n\n第一，Docker 中的 RABBITMQ 請繼續執行著，不要關掉。\n\n第二，請記得安裝 Celery Library 以及 SQLAlchemy ( 因為 result_backend 默認是用 ORM )。\n\n也可以從 celery-demo/[requirements.txt](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/celery-demo/requirements.txt) 直接一次安裝，直接在 Terminal 執行以下指令\n\n```cmd\npip install -r requirements.txt\n```\n\n上面這段指令，我已經包進去 celery-demo/[Dockerfile](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/celery-demo/Dockerfile) 了，\n\n也用 docker 幫大家包成 celery-demo/[docker-compose.yml](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/celery-demo/docker-compose.yml) 了，所以直接執行以下指令即可\n\n```cmd\ndocker-compose up\n```\n\n![alt tag](https://i.imgur.com/SEiVJu0.png)\n\n這樣基本上就啟動成功了:smiley:\n\n以下我將簡單介紹  [celery-demo](https://github.com/twtrubiks/docker-django-celery-tutorial/tree/master/celery-demo)  裡面的檔案，\n\ncelery_app/[`__init__.py`](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/celery-demo/celery_app/__init__.py)\n\n```python\nfrom celery import Celery\n\napp = Celery('demo', broker='amqp://celery:password123@rabbitmq:5672/my_vhost')\napp.config_from_object('celery_app.celery_config')\n```\n\n這邊主要是設定你的 broker （ 在這邊我們的 broker 就是 RABBITMQ ），\n\n最後一行只是載入我們定義的 config 檔而已，\n\n接著來看看 config 檔到底設定了什麼:wink:\n\ncelery_app/[celery_config.py](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/celery-demo/celery_app/celery_config.py)\n\n```python\nfrom datetime import timedelta\n\nfrom celery.schedules import crontab\n\n# Timezone\ntimezone = 'Asia/Taipei'\n\n# import\nimports = (\n    'celery_app.tasks',\n)\n\n# result\nresult_backend = 'db+sqlite:///results.sqlite'\n\n# schedules\nbeat_schedule = {\n    'every-2-seconds': {\n        'task': 'celery_app.tasks.add',\n        'schedule': timedelta(seconds=2),\n        'args': (5, 8)\n    },\n    'specified-time': {\n        'task': 'celery_app.tasks.add',\n        'schedule': crontab(hour=8, minute=50),\n        'args': (50, 50)\n    }\n\n}\n```\n\n`imports` 的部份就是等等我會介紹的 celery-demo/[tasks.py](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/celery-demo/celery_app/tasks.py)。\n\n`result_backend` 這部份的設定是可以將 Celery 執行的結果儲存起來。\n\n`beat_schedule` 這部份的設定則是 schedule，schedule 後面我會再進一步介紹。\n\nCelery 可以設定的參數非常多，詳細可參考 [configuration-and-defaults](https://docs.celeryq.dev/en/latest/userguide/configuration.html#configuration-and-defaults)。\n\n接著來介紹 celery_app/[tasks.py](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/celery-demo/celery_app/tasks.py)\n\n```python\nimport time\n\nfrom celery_app import app\n\n\n@app.task\ndef add(x, y):\n    return x + y\n```\n\n這邊設定了一個很簡單的 task，那我要怎麼執行 :question::question: 請用你的 Terminal 執行這個 worker （很重要），\n\n```cmd\ncelery -A celery_app worker -l info\n```\n\n上面這段指令，我已經包進去 celery-demo/[docker-compose.yml](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/celery-demo/docker-compose.yml) 的 command 了，\n\n接著就可以在你的 Python Console ( docker 容器中 ) 開始玩  Celery 了 :satisfied:\n\n在  Python Console 中我們輸入以下程式碼\n\n```python\nfrom celery_app.tasks import add\nadd.delay(2,2).get()\n```\n\n![alt tag](https://i.imgur.com/hZFWlUn.png)\n\n執行後你會發現目錄中多出了 celery-demo/[results.sqlite](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/celery-demo/results.sqlite)，這個是我們前面所設定的 `result_backend`，\n\n裡面存放著 Celery 的執行結果，\n\n![alt tag](https://i.imgur.com/cunFhuo.png)\n\n如果想要取回 result, 可以透過以下方式,\n\n```python\nfrom celery.result import AsyncResult\nfrom celery_app import app\n\nres = AsyncResult('4c709f53-fc81-4ae9-830d-f15198dd4102', app=app)\n\u003e\u003e\u003e res.state\n'SUCCESS'\n\u003e\u003e\u003e res.get()\n4\n```\n\nCelery 還有很多指令，像是 Chains , Groups , Chords 之類的，基本上就用我這個範例，\n\n你就可以把其他的指令都玩玩看，可參考 [Canvas: Designing Work-flows](http://docs.celeryproject.org/en/latest/userguide/canvas.html)，\n\n在我的 celery_app/[tasks.py](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/celery-demo/celery_app/tasks.py) 中，還有一段程式碼\n\n```python\n'''\nref. http://docs.celeryq.org/en/latest/userguide/tasks.html#avoid-launching-synchronous-subtasks\n'''\n\ndef chain_demo(x, y):\n    # add_demo -\u003e  mul_demo -\u003e insert_db_demo\n    chain(add_demo.s(x, y), mul_demo.s(10), insert_db_demo.s())()\n\n\n@app.task\ndef add_demo(x, y):\n    time.sleep(3)\n    return x + y\n\n\n@app.task\ndef mul_demo(x, y):\n    time.sleep(3)\n    return x * y\n\n\n@app.task(ignore_result=True)\ndef insert_db_demo(result):\n    print('insert db , result {}'.format(result))\n\n```\n\n一樣記得要先啟動 worker，\n\n```cmd\ncelery -A celery_app worker -l info\n```\n\n上面這段指令，我已經包進去 celery-demo/[docker-compose.yml](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/celery-demo/docker-compose.yml) 的 command 了，\n\n在 Python Console ( docker 容器中 ) 輸入下方程式碼\n\n```python\nfrom celery_app.tasks import chain_demo\nchain_demo(1,1)\n```\n\n![alt tag](https://i.imgur.com/PbEjh3s.png)\n\n![alt tag](https://i.imgur.com/MvSByNV.png)\n\n建議可以先去觀看一下 Celery 中的  [signatures](http://docs.celeryproject.org/en/latest/userguide/canvas.html#signatures)，不然你可能會看不懂這段 code，\n\nCelery 的官方文件我覺得真的不錯，可以多看 :satisfied:\n\n像這段程式碼，就是使用了 celery 中 chain 的概念，我簡單說明一下，這邊有三個 task ，\n\n當我們執行 `chain_demo(1,1)` 的時候，會先執行 `add_demo` 並且回傳 2 ，接著 2 會被傳入\n\n`mul_demo` ，這時候 x = 2，y = 10，回傳 2*10 = 20 ( 這邊補充一下，`time.sleep(3)` 的用意\n\n是模擬這個 task 需要時間執行 )，最後再將 20 傳入 `insert_db_demo`。\n\n這邊有一個裝飾器 `@app.task(ignore_result=True)` ，目的主要是忽略結果不寫入 [results.sqlite](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/celery-demo/results.sqlite)\n\n，如果你的結果沒有很重要，可以加上這個裝飾器，避免不必要的開銷，\n\n可參考官方的說明 [Ignore results you don't want](https://docs.celeryq.dev/en/latest/userguide/tasks.html#ignore-results-you-don-t-want)\n\n### Flower - Celery monitoring tool\n\n在 [監控 Celery](https://github.com/twtrubiks/django-celery-tutorial#%E7%9B%A3%E6%8E%A7-celery) 這邊有提過了,\n\n這裡我把它包成 docker, [flower_service/Dockerfile](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/django_crawler_celery/flower_service/Dockerfile) 是參考下面的 Dockerfile 重新自己 build 一個,\n\n[https://github.com/mher/flower/blob/master/Dockerfile](https://github.com/mher/flower/blob/master/Dockerfile)\n\n直接瀏覽 [http://localhost:5555/](http://localhost:5555/) 即可.\n\n還記得我們有一個 schedule 還沒有講嘛:question:\n\n接下來我就來介紹 schedule :smirk:\n\n### Periodic Tasks\n\n建議可以閱讀官方的文件，可參考 [Periodic Tasks](https://docs.celeryq.dev/en/latest/userguide/periodic-tasks.html)。\n\nCelery 的 schedule 真的還不錯，可以很簡單的設定 schedule，\n\n它類似 Linux 上的 [Linux 指令教學-Crontab](https://github.com/twtrubiks/linux-note/tree/master/crontab-tutorual),\n\ncelery beat 指令如下 ,\n\n```cmd\ncelery -A celery_app beat\n```\n\n上面這段指令，用 docker 幫大家包成 celery-demo/[docker-compose.yml](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/celery-demo/docker-compose.yml) 了，\n\n![alt tag](https://i.imgur.com/rqTK3bB.png)\n\n![alt tag](https://i.imgur.com/jtKLNX7.png)\n\n你會發現多了一個 celery-demo/[celerybeat-schedule](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/celery-demo/celerybeat-schedule.db) ，這個檔案是儲存了一些 schedule 的資料，\n\n還記得剛剛前面設定的東西嗎 :grinning:\n\n```python\n# schedules\nbeat_schedule = {\n    'every-2-seconds': {\n        'task': 'celery_app.tasks.add',\n        'schedule': timedelta(seconds=2),\n        'args': (5, 8)\n    },\n    'specified-time': {\n        'task': 'celery_app.tasks.add',\n        'schedule': crontab(hour=8, minute=50),\n        'args': (50, 50)\n    }\n\n}\n```\n\n`every-2-seconds` 這個每兩秒會呼叫 add task ，並且傳入參數 (5,8) 。\n\n`specified-time` 這個為每天的早上 8 點 50 分會去呼叫 add task ，並且傳入參數 (50,80)  ，\n\n![alt tag](https://i.imgur.com/NfcqjPt.png)\n\n這個要注意時區，我們在前面有設定時區為 `timezone = 'Asia/Taipei'`，更多的 schedule\n\n設定方法可參考 [crontab-schedules](https://docs.celeryq.dev/en/latest/userguide/periodic-tasks.html#crontab-schedules)\n\n## 實戰 Django + Celery\n\n建議搭配影片看比較好理解 :blush:\n\n* [Youtube Tutorial Part3 - 實戰 Django + Celery ( 使用 Docker )](https://youtu.be/3dwRrJml2NQ)\n\n在 [這篇](https://github.com/twtrubiks/django-celery-tutorial) 的教學中，我們使用了發送 e-mail 當做例子，但在這邊，我們換個例子，模擬爬蟲（透過 github api 爬 repos），\n\n然後再模擬轉檔，這邊其實就是簡單將他轉成 csv 檔而已，當前端按下開始抓取的時候，我們很快的回傳  task id  給前端\n\n（使用者這時候可以繼續的瀏覽網頁其他的資訊 ），讓爬蟲以及轉檔在背景處理，使用者可以透過 task id 查詢任務是否\n\n完成（或是說任務完成後寄一封信通知使用者也是可以 :relaxed: ）\n\n詳細的 Django + Celery 設定教學，這邊就不再做介紹，可參考之前 [這篇](https://github.com/twtrubiks/django-celery-tutorial)  的教學 ，或是可以直接參考 Celery 的官網教學\n\n [First steps with Django](http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html)，我也是參考這篇教學的 :smile:\n\n在開始介紹前，先簡單的介紹一下 github API ，我們要先取得 token，取得 token 的方法也很簡單，\n\n可參考 [Creating a token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/#creating-a-token)，取得 token 後，\n\n先來試試看一下 api，這邊用 [curl](https://curl.haxx.se/)\n\n( 請記得換上你自己的 token )\n\n```cmd\ncurl -H \"Authorization: token 7f304579ba192b9d351aa8468e09dd9dca29ff31\" \"https://api.github.com/search/repositories?q=twtrubiks\"\n```\n\n也可以使用 [postman](https://www.getpostman.com/)，請參考下圖\n\n![alt tag](https://i.imgur.com/H4Y1N6Z.png)\n\n確認正常後，我們再進行下一步驟。\n\n終於到了我們實戰的步驟了:satisfied:\n\n我用 docker 幫大家包成 [docker-compose.yml](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/django_crawler_celery/docker-compose.yml) 了，所以直接執行以下指令即可\n\n```cmd\ndocker-compose up\n```\n\n![alt tag](https://i.imgur.com/kjWyLw4.png)\n\n執行範例時，請啟動記得 RabbitMQ 以及執行 worker，也就是執行\n\n```python\ncelery -A django_crawler_celery worker -l info\n```\n\n上面這段指令，我已經包進去 django_crawler_celery/\n[docker-compose.yml](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/django_crawler_celery/docker-compose.yml) 的 command 了，\n\n我們來看一下 django_crawler_celery/tutorial/\n[tasks.py](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/django_crawler_celery/tutorial/tasks.py)\n\n```python\ndef chain_tasks(language):\n    # crawler_repos -\u003e  build_report_task\n    task_id = uuid()\n    chain(crawler_repos.s(language, 1000, 1), build_report_task.subtask(args=(task_id,), task_id=task_id))()\n    return task_id\n\n\n'''\nref. http://docs.celeryq.org/en/latest/userguide/tasks.html#ignore-results-you-don-t-want\n'''\n\n\n@shared_task(ignore_result=True)\ndef crawler_repos(language, per_page, page):\n    payload = {\n        'sort': 'stars',\n        'order': 'desc',\n        'q': 'language:{}'.format(language),\n        'per_page': per_page,\n        'page': page\n    }\n    headers = {\n        'Accept': 'application/vnd.github.v3+json',\n        'Authorization': 'token {}'.format(settings.GITHUB_OAUTH)\n    }\n    r = requests.get(\n        'https://api.github.com/search/repositories',\n        params=payload,\n        headers=headers)\n\n    # Simulation file conversion\n    time.sleep(10)\n\n    items = r.json()['items']\n    return items\n\n\n@shared_task\ndef build_report_task(results, task_id):\n    rows = [\n        [repo.get('name'), repo.get('full_name'), repo.get('html_url'), repo.get('description')]\n        for repo in results\n    ]\n    filename = '{}/github-repos-{}.csv'.format(settings.MEDIA_ROOT, task_id)\n\n    # Simulation file conversion\n    time.sleep(10)\n\n    return create_csv(filename, rows)\n\n```\n\n這邊我一樣使用前面介紹的 chain 概念來完成，有兩個 tasks ，分別為 `crawler_repos` 以及 `build_report_task`，\n\n`crawler_repos` 主要是透過 github api 抓取指定語言的 repos，這邊是用 stars 多到少進行排序，詳細的 github api\n\n參數可參考 [github serach api](https://developer.github.com/v3/search/#search)，\n`build_report_task` 則是將結果輸出為 csv ，這邊一樣再提一下，`time.sleep(10)`\n\n主要是要模擬需要一些時間才執行的完。\n\n### django-celery-results\n\n還記得前面有說到一個儲存 Celery 結果的 db 嗎？ 就是前面提到的 [results.sqlite](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/celery-demo/results.sqlite)，同樣的在 Django 中，我們可以透過\n\n [django-celery-results](https://pypi.python.org/pypi/django-celery-results/) 並且利用 ORM 的方式來讀取裡面的資料，\n\n 詳細可參考 [Using the Django ORM/Cache as a result backend](http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html#django-celery-results-using-the-django-orm-cache-as-a-result-backend)，\n\n簡單說明一下流程，首先先安裝 Library，請在命令列執行\n\n```python\npip install django-celery-results\n```\n\n加入 django_celery_results 到 django_crawler_celery/[settings.py](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/django_crawler_celery/django_crawler_celery/settings.py) 中\n\n```python\nINSTALLED_APPS = (\n    ...,\n    'django_celery_results',\n)\n```\n\n接著  migration  database\n\n```cmd\npython manage.py migrate django_celery_results\n```\n\n![alt tag](https://i.imgur.com/u9e9Sdn.png)\n\n這時候你會發現，你的 db 中多了 `django_celery_results_taskresult`\n\n![alt tag](https://i.imgur.com/nSqkEDP.png)\n\n最後在設定一下你的 backend\n\n```python\nCELERY_RESULT_BACKEND = 'django-db'\n```\n\n現在我們就可以透過 ORM 的方式操作裡面的資料了，使用方法很簡單，就 Django ORM，\n\n記得 import `TaskResult`，可參考下方程式碼\n\n```python\nfrom django_celery_results.models import TaskResult\nTaskResult.objects.all()\n```\n\nTaskResult 的 model 可參考 [models.py](https://github.com/celery/django-celery-results/blob/master/django_celery_results/models.py)。\n\n以上步驟我只是說明一下，我都幫大家包進去 django_crawler_celery/[docker-compose.yml](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/django_crawler_celery/docker-compose.yml) 的 command 了:blush:\n\n## 執行畫面\n\n這邊簡單 demo 一下 Django + Celery + Flower 的成果，\n\n```cmd\ndocker-compose up\n```\n\n直接瀏覽 [http://127.0.0.1:8000/](http://127.0.0.1:8000/)，\n\n![alt tag](https://i.imgur.com/LyV40it.png)\n\n當按下 start crawler github 按鈕時，Celery 會開始爬蟲+轉檔，我會很快得先回傳一個 task id 給前端，\n\n我們來看一下 django_crawler_celery/tutorial/\n[views.py](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/django_crawler_celery/tutorial/views.py)\n\n```python\n@require_http_methods([\"POST\", ])\n@csrf_exempt\ndef task_use_celery(request):\n    if request.method == 'POST':\n        task_id = chain_tasks('python')\n        return JsonResponse({\"data\": task_id})\n```\n\n當你按下按鈕就是去呼叫 `task_use_celery`，然後會去執行 `chain_tasks` ，裡面就是 Celery 的 tasks，\n\n這邊用了一個裝飾器 `@csrf_exempt`，這個主要是先忽略 CSRF 的問題，如果不知道什麼是 CSRF，\n\n可參考我之前介紹的 [CSRF-tutorial](https://github.com/twtrubiks/CSRF-tutorial)。\n\n當爬蟲以及成功輸出成 csv 檔之後，就可以在 datatable 中查詢到，\n\ndatatable 的部份其實就是透過 [django-celery-results](https://pypi.python.org/pypi/django_celery_results) 利用 ORM 的方式將資料撈出來而已，\n\n可參考 django_crawler_celery/tutorial/\n[views.py](https://github.com/twtrubiks/docker-django-celery-tutorial/blob/master/django_crawler_celery/tutorial/views.py)\n\n```python\ndef dashboard(request):\n    results = TaskResult.objects.all()\n    return render(request,\n                  'tutorial/dashboard.html',\n                  {'results': results})\n```\n\n![alt tag](https://i.imgur.com/CHBUE6Z.png)\n\nCelery 在背景執行 task\n\n![alt tag](https://i.imgur.com/J9di9vD.png)\n\ntask 執行完成後，可在 datatable 中看到\n\n![alt tag](https://i.imgur.com/EyjMnEN.png)\n\n也可以到 flower 中查看, 瀏覽 [http://localhost:5555/](http://localhost:5555/)\n\n## 後記\n\n這次帶大家用 docker 建立 Celery 環境，相信大家一定覺得很方便，也解決了很多\n\n環境上的問題。Celery 使用情境真的蠻多的，大家有興趣的話可以多玩玩看:laughing:\n\n## 執行環境\n\n* Python 3.8\n\n## Reference\n\n* [Django](https://www.djangoproject.com/)\n* [Celery](http://celery.readthedocs.io/en/latest/index.html)\n* [Flower](https://flower.readthedocs.io/en/latest/)\n\n## Donation\n\n文章都是我自己研究內化後原創，如果有幫助到您，也想鼓勵我的話，歡迎請我喝一杯咖啡:laughing:\n\n![alt tag](https://i.imgur.com/LRct9xa.png)\n\n[贊助者付款](https://payment.opay.tw/Broadcaster/Donate/9E47FDEF85ABE383A0F5FC6A218606F8)\n\n## License\n\nMIT licens\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwtrubiks%2Fdocker-django-celery-tutorial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftwtrubiks%2Fdocker-django-celery-tutorial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwtrubiks%2Fdocker-django-celery-tutorial/lists"}