Docker构建Django+React应用时修改venv中模块代码的方法
解决Docker构建时保留django-rest-multiple-models代码修改的方案
问题背景
我用React做前端,Django(搭配Django REST Framework)做API后端。之前修改了依赖的django-rest-multiple-models==2.1.3模块里的两行代码,把原代码中的__name__替换成了verbose_name,但Docker构建时不会把本地的.venv文件夹复制到容器里,导致修改无法保留,现在需要找到在构建阶段完成这个代码修改的方法。
修改后的目标代码
原模块中drf_multiple_model目录下的get_label函数(对应第196-207行)修改后如下:
def get_label(self, queryset, query_data): """ Gets option label for each datum. Can be used for type identification of individual serialized objects """ if query_data.get('label', False): return query_data['label'] elif self.add_model_type: try: return queryset.model._meta.verbose_name except AttributeError: return query_data['queryset'].model._meta.verbose_name
当前的Docker配置
Dockerfile
FROM python:3.10-alpine ENV PYTHONUNBUFFERED 1 WORKDIR /server COPY requirements.txt requirements.txt RUN pip3 install -r requirements.txt COPY . .
docker-compose.yml
version: '3' services: backend: build: context: ./server command: gunicorn core.wsgi --bind 0.0.0.0:8000 ports: - "8000:8000" expose: - 8000 depends_on: - postgres
可行解决方案
方案1:用sed命令在构建时直接替换代码
修改Dockerfile,在安装依赖后添加sed命令,直接修改容器内的模块文件:
FROM python:3.10-alpine ENV PYTHONUNBUFFERED 1 WORKDIR /server COPY requirements.txt requirements.txt RUN pip3 install -r requirements.txt \ # 动态获取模块路径,替换两处__name__为verbose_name && MODULE_PATH=$(python -c "import drf_multiple_model; print(drf_multiple_model.__file__.replace('__init__.py', 'views.py'))") \ && sed -i "s/return queryset.model._meta.__name__/return queryset.model._meta.verbose_name/" $MODULE_PATH \ && sed -i "s/return query_data\['queryset'\].model._meta.__name__/return query_data['queryset'].model._meta.verbose_name/" $MODULE_PATH COPY . .
- 用Python命令动态获取模块路径,不用硬编码,避免不同环境路径不一致的问题
sed命令直接替换目标字符串,一步完成修改
方案2:创建补丁文件,构建时应用补丁
- 在
./server目录下创建补丁文件drf_multiple_model.patch,内容如下:
--- a/views.py +++ b/views.py @@ -199,7 +199,7 @@ class FlatMultipleModelMixin(object): elif self.add_model_type: try: - return queryset.model._meta.__name__ + return queryset.model._meta.verbose_name except AttributeError: - return query_data['queryset'].model._meta.__name__ + return query_data['queryset'].model._meta.verbose_name
- 修改Dockerfile,先安装
patch工具,再应用补丁:
FROM python:3.10-alpine ENV PYTHONUNBUFFERED 1 WORKDIR /server COPY requirements.txt requirements.txt COPY drf_multiple_model.patch drf_multiple_model.patch RUN apk add --no-cache patch \ && pip3 install -r requirements.txt \ && MODULE_PATH=$(python -c "import drf_multiple_model; print(drf_multiple_model.__file__.replace('__init__.py', 'views.py'))") \ && patch $MODULE_PATH < drf_multiple_model.patch COPY . .
- 补丁文件能清晰记录修改内容,后续调整更方便
- Alpine镜像默认没有
patch,所以要先安装
方案3:fork原模块维护自定义版本
如果之后还要改这个模块的代码,直接fork原仓库,把修改推到自己的分支,然后在requirements.txt里替换成自定义版本:
# 替换原来的django-rest-multiple-models依赖行 git+https://github.com/你的用户名/django-rest-multiple-models.git@你的分支名#egg=django-rest-multiple-models==2.1.3
这种方式最稳定,适合长期维护自定义修改。
内容的提问来源于stack exchange,提问作者aboka
相关产品推荐
相关产品推荐

