#django #docker #django-rest-framework #docker-compose
#django #docker #django-rest-framework #docker-compose
Вопрос:
В Django я хочу выполнить задачу сельдерея (скажем, добавить 2 числа), когда пользователь загружает новый файл /media
. Что я сделал, так это использовал signals
so при сохранении связанного объекта загрузки, задача сельдерея будет запущена.
Вот мой код и конфигурация Docker:
signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from core.models import Upload
from core.tasks import add_me
def upload_save(sender, instance, signal, *args, **kwargs):
print("IN UPLOAD SIGNAL") # <----- LOGS PRINT UP TO HERE, IN CONTAINERS
add_me.delay(10)
post_save.connect(upload_save, sender=Upload) # My post save signal
tasks.py
from celery import shared_task
@shared_task(ignore_result=True, max_retries=3)
def add_me(upload_id):
print('In celery') # <----- This is not printed when in Docker!
return upload_id 20
views.py
class UploadView(mixins.CreateModelMixin, generics.GenericAPIView):
serializer_class = UploadSerializer
def post(self, request, *args, **kwargs):
serializer = UploadSerializer(data=request.data)
print("SECOND AFTER")
print(request.data) <------ I can see my file name here
if serializer.is_valid():
print("THIRD AFTER") <------ This is printer OK in all cases
serializer.save()
print("FOURTH AFTER") <----- But this is not printed when in Docker!
return response.Response(
{"Message": "Your file was uploaded"},
status=status.HTTP_201_CREATED,
)
return response.Response(
{"Message": "Failure", "Errors": serializer.errors},
status=status.HTTP_403_FORBIDDEN,
)
docker-compose.yml
version: "3.8"
services:
db:
# build: ./database_docker/
image: postgres
ports:
- "5432:5432"
environment:
POSTGRES_DB: test_db
POSTGRES_USER: test_user
POSTGRES_PASSWORD: test_pass
# volumes:
# - media:/code/media
web:
build: ./docker/
command: bash -c "python manage.py migrate --noinput amp;amp; python manage.py runserver 0.0.0.0:8000"
volumes:
- .:/code
- media:/code/media
ports:
- "8000:8000"
depends_on:
- db
rabbitmq:
image: rabbitmq:3.6.10
volumes:
- media:/code/media
worker:
build: ./docker/
command: celery -A example_worker worker --loglevel=debug -n worker1.%h
volumes:
- .:/code
- media:/code/media
depends_on:
- db
- rabbitmq
volumes:
media:
Dockerfile
FROM python:latest
ENV PYTHONUNBUFFERED=1
WORKDIR /code
COPY requirements.txt /code/
RUN pip3 install -r requirements.txt
COPY . /code/
WORKDIR /code
Все работает нормально, когда не в Docker.
Проблема в том, что когда я развертываю вышеупомянутое в Docker и пытаюсь загрузить файл, запрос никогда не завершается, хотя файл загружен в media
папку (подтвердил это, обратившись к его содержимому как web
в контейнерах, так и worker
в контейнерах).
Более конкретно, кажется, что задача сельдерея не выполняется (завершена?), А код после serializer.save()
никогда не достигается.
Когда я удаляю сигнал (таким образом, задача сельдерея не запускается), все в порядке. Может кто-нибудь мне помочь?
Ответ №1:
Я только что понял это. Оказывается, мне нужно добавить следующее в __init__.py
мое приложение.
from .celery import app as celery_app
__all__ = ("celery_app",)
Не знаю, почему все работает гладко без этого фрагмента кода, когда я не использую контейнеры…