Django通过脚本上传文件的详细操作指南

Written by

in

文章目录
  • “”” Django 脚本上传文件到 ImageField 完整示例 “”” import os import sys import django from pathlib import Path from django.core.files import File import logging # 配置日志 logger = logging.getLogger(__name__) logging.basicConfig( level=logging.INFO, format=’%(asctime)s – %(name)s – %(levelname)s – %(message)s’, handlers=[ logging.FileHandler(‘upload_script.log’), logging.StreamHandler() ] ) def setup_django(): “””配置 Django 环境””” # 获取项目根目录 BASE_DIR = Path(__file__).resolve().parent.parent.parent # 添加到系统路径 sys.path.append(str(BASE_DIR)) # 设置 Django 环境变量 os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’, ‘yunCoolCinema.settings’) # 初始化 Django django.setup() # 导入 Django 设置 from django.conf import settings return settings def upload_file_to_model(model, file_path, field_name=’avatar’, **kwargs): “”” 上传文件到模型字段 :param model: 模型实例 :param file_path: 文件路径 :param field_name: 字段名称 :param kwargs: 模型过滤条件 :return: 更新后的模型实例 “”” # 获取文件字段 file_field = getattr(model, field_name) # 打开文件 with open(file_path, ‘rb’) as f: # 保存文件到字段 file_field.save( Path(file_path).name, # 文件名 File(f), # 文件内容,转换成django内部的文件对象 save=True # 保存模型 ) logger.info(‘文件已上传: %s -> %s’, file_path, file_field.path) return model def main(): “””主函数””” # 1. 设置 Django 环境 settings = setup_django() logger.info(‘Django 环境设置完成’) # 2. 导入模型 from actors.models import Actor # 3. 设置文件目录 file_dir = Path(‘data/portrait’) # 文件源目录 if not file_dir.exists(): logger.error(‘文件目录不存在: %s’, file_dir) return # 4. 获取演员和文件映射 # 假设文件名格式: {演员姓名}.jpg file_map = {} for file_path in file_dir.glob(‘*.*’): if file_path.suffix.lower() in [‘.jpg’, ‘.jpeg’, ‘.png’]: actor_name = file_path.stem # 文件名(不带扩展名) file_map[actor_name] = file_path # 5. 批量上传文件 success_count = 0 for actor_name, file_path in file_map.items(): try: # 获取演员对象 actor = Actor.objects.get(name=actor_name) # 上传文件 upload_file_to_model(actor, file_path) success_count += 1 except Actor.DoesNotExist: logger.warning(‘演员不存在: %s’, actor_name) except Exception as e: logger.error(‘上传失败: %s – %s’, actor_name, str(e)) logger.info(‘文件上传完成: 成功 %d 个’, success_count) if __name__ == “__main__”: main()
  • 通过本教程,您学会了: 如何配置 Django 脚本环境 如何通过脚本上传文件到 ImageField 文件保存路径的处理机制 生产环境的最佳实践 关键点: 使用 file_field.save() 方法上传文件 确保 MEDIA_ROOT 正确配置 文件将自动保存到 MEDIA_ROOT/upload_to/ 目录 数据库记录相对路径(相对于 MEDIA_ROOT) 通过实现这些技术,您可以轻松地通过脚本将文件上传到 Django 的 ImageField 字段,并确保文件保存在正确的位置。 以上就是Django通过脚本上传文件的详细操作指南的详细内容,更多关于Django脚本上传文件的资料请关注风君子博客其它相关文章! 您可能感兴趣的文章: Django+simpleui实现文件上传预览功能(详细过程) Python web实战教程之Django文件上传和处理详解 使用Django+Vue编写一个文件上传器 Django+Vue实现文件上传下载的项目实践 vue与django(drf)实现文件上传下载功能全过程
  • 目录
    • 一、核心概念
      • 1. Django 文件字段
      • 2. 媒体文件系统
    • 二、完整脚本示例
      • 三、关键步骤详解
        • 1. 配置 Django 环境
        • 2. 文件上传核心函数
        • 3. 路径保存机制
      • 四、路径保存注意事项
        • 1. 正确配置 settings.py
        • 2. URL 配置
        • 3. 文件名处理技巧
        • 4. 避免路径冲突
      • 五、高级功能扩展
        • 1. 批量上传优化
        • 2. 添加进度显示
        • 3. 文件验证
        • 4. 错误处理增强
      • 六、生产环境最佳实践
        • 1. 使用云存储
        • 2. 添加文件清理
        • 3. 使用缓存加速
      • 七、完整工作流程
        • 1. 准备环境
        • 2. 文件目录结构
        • 3. 运行脚本
        • 4. 验证结果
      • 八、常见问题解答
        • Q1: 文件保存在哪里?
        • Q2: 如何访问上传的文件?
        • Q3: 文件名冲突怎么办?
        • Q4: 如何删除旧文件?
      • 九、总结

        • ImageField:用于存储图片文件
        • FileField:用于存储任意文件类型
        • upload_to:指定文件存储的子目录

        • MEDIA_ROOT:文件在服务器上的存储路径
        • MEDIA_URL:文件访问的 URL 前缀
        • 文件保存流程
          文件上传 → 保存到 MEDIA_ROOT/upload_to/ → 数据库记录路径

        """
        Django 脚本上传文件到 ImageField 完整示例
        """
        
        import os
        import sys
        import django
        from pathlib import Path
        from django.core.files import File
        import logging
        
        # 配置日志
        logger = logging.getLogger(__name__)
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('upload_script.log'),
                logging.StreamHandler()
            ]
        )
        
        def setup_django():
            """配置 Django 环境"""
            # 获取项目根目录
            BASE_DIR = Path(__file__).resolve().parent.parent.parent
            
            # 添加到系统路径
            sys.path.append(str(BASE_DIR))
            
            # 设置 Django 环境变量
            os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'yunCoolCinema.settings')
            
            # 初始化 Django
            django.setup()
            
            # 导入 Django 设置
            from django.conf import settings
            return settings
        
        def upload_file_to_model(model, file_path, field_name='avatar', **kwargs):
            """
            上传文件到模型字段
            :param model: 模型实例
            :param file_path: 文件路径
            :param field_name: 字段名称
            :param kwargs: 模型过滤条件
            :return: 更新后的模型实例
            """
            # 获取文件字段
            file_field = getattr(model, field_name)
            
            # 打开文件
            with open(file_path, 'rb') as f:
                # 保存文件到字段
                file_field.save(
                    Path(file_path).name,  # 文件名
                    File(f),               # 文件内容,转换成django内部的文件对象
                    save=True              # 保存模型
                )
            
            logger.info('文件已上传: %s -> %s', file_path, file_field.path)
            return model
        
        def main():
            """主函数"""
            # 1. 设置 Django 环境
            settings = setup_django()
            logger.info('Django 环境设置完成')
            
            # 2. 导入模型
            from actors.models import Actor
            
            # 3. 设置文件目录
            file_dir = Path('data/portrait')  # 文件源目录
            if not file_dir.exists():
                logger.error('文件目录不存在: %s', file_dir)
                return
            
            # 4. 获取演员和文件映射
            # 假设文件名格式: {演员姓名}.jpg
            file_map = {}
            for file_path in file_dir.glob('*.*'):
                if file_path.suffix.lower() in ['.jpg', '.jpeg', '.png']:
                    actor_name = file_path.stem  # 文件名(不带扩展名)
                    file_map[actor_name] = file_path
            
            # 5. 批量上传文件
            success_count = 0
            for actor_name, file_path in file_map.items():
                try:
                    # 获取演员对象
                    actor = Actor.objects.get(name=actor_name)
                    
                    # 上传文件
                    upload_file_to_model(actor, file_path)
                    success_count += 1
                    
                except Actor.DoesNotExist:
                    logger.warning('演员不存在: %s', actor_name)
                except Exception as e:
                    logger.error('上传失败: %s - %s', actor_name, str(e))
            
            logger.info('文件上传完成: 成功 %d 个', success_count)
        
        if __name__ == "__main__":
            main()
        

        def setup_django():
            BASE_DIR = Path(__file__).resolve().parent.parent.parent
            sys.path.append(str(BASE_DIR))
            os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'yunCoolCinema.settings')
            django.setup()
            from django.conf import settings
            return settings
        
        • 作用:使脚本能访问 Django 模型和设置
        • 注意:根据项目结构调整路径层级

        def upload_file_to_model(model, file_path, field_name='avatar', **kwargs):
            file_field = getattr(model, field_name)
            with open(file_path, 'rb') as f:
                file_field.save(
                    Path(file_path).name,  # 文件名
                    File(f),              # 文件内容
                    save=True             # 保存模型
                )
        
        • 核心方法file_field.save()
        • 参数说明
          • 第一个参数:保存的文件名
          • 第二个参数:File 对象
          • save=True:自动保存模型到数据库

        # 上传后文件保存位置
        file_path = model.avatar.path  # 物理路径: MEDIA_ROOT/portrait/filename.jpg
        file_url = model.avatar.url    # 访问URL: MEDIA_URL/portrait/filename.jpg
        
        • 存储位置MEDIA_ROOT/upload_to/filename
        • 自动处理:Django 自动处理文件存储和路径记录

        # settings.py
        
        # 媒体文件配置
        MEDIA_URL = '/media/'  # 访问URL
        MEDIA_ROOT = os.path.join(BASE_DIR, 'media')  # 文件存储路径
        

        # urls.py
        from django.conf import settings
        from django.conf.urls.static import static
        
        urlpatterns = [
            # ...其他URL...
        ]
        
        if settings.DEBUG:
            urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
        

        # 自定义文件名
        def custom_filename(instance, filename):
            """生成自定义文件名"""
            return f"portrait/{instance.id}_{filename}"
        
        # 在模型中
        avatar = models.ImageField(upload_to=custom_filename)
        

        import uuid
        
        def unique_filename(instance, filename):
            """生成唯一文件名"""
            ext = filename.split('.')[-1]
            return f"portrait/{uuid.uuid4().hex}.{ext}"
        

        def bulk_upload(models, file_map, field_name):
            """批量上传文件"""
            for model in models:
                if model.name in file_map:
                    upload_file_to_model(model, file_map[model.name], field_name)
        

        from tqdm import tqdm
        
        # 在循环中使用
        for actor_name, file_path in tqdm(file_map.items(), desc="上传文件"):
            # 上传逻辑
        

        from django.core.exceptions import ValidationError
        
        def validate_image(file_path):
            """验证图片文件"""
            # 检查文件大小
            if file_path.stat().st_size > 5 * 1024 * 1024:  # 5MB
                raise ValidationError("文件大小超过限制")
            
            # 检查文件类型
            if file_path.suffix.lower() not in ['.jpg', '.jpeg', '.png']:
                raise ValidationError("不支持的文件类型")
        

        try:
            upload_file_to_model(actor, file_path)
        except OSError as e:
            logger.error('文件操作错误: %s', str(e))
        except django.db.utils.IntegrityError as e:
            logger.error('数据库错误: %s', str(e))
        except Exception as e:
            logger.exception('未知错误')
        

        # settings.py
        DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
        AWS_ACCESS_KEY_ID = 'your-access-key'
        AWS_SECRET_ACCESS_KEY = 'your-secret-key'
        AWS_STORAGE_BUCKET_NAME = 'your-bucket-name'
        AWS_S3_REGION_NAME = 'your-region'
        

        def cleanup_old_file(model, field_name):
            """清理旧文件"""
            old_file = getattr(model, field_name)
            if old_file and old_file.name:
                old_file.delete(save=False)  # 删除文件但不保存模型
        

        from django.core.cache import cache
        
        def get_cached_model(model_class, pk):
            """获取缓存模型"""
            cache_key = f"{model_class.__name__}_{pk}"
            model = cache.get(cache_key)
            if not model:
                model = model_class.objects.get(pk=pk)
                cache.set(cache_key, model, timeout=60 * 60)  # 缓存1小时
            return model
        

        # 创建虚拟环境
        python -m venv .venv
        source .venv/bin/activate  # Linux/macOS
        ..venvScriptsactivate   # Windows
        
        # 安装依赖
        pip install django tqdm
        

        project/
        ├── manage.py
        ├── media/                  # 上传的文件存储位置 (自动创建)
        ├── data/                   # 原始文件目录
        │   └── portrait/
        │       ├── 张艺谋.jpg
        │       └── 巩俐.png
        ├── scripts/
        │   └── upload_files.py     # 上传脚本
        └── yunCoolCinema/
            ├── settings.py
            ├── urls.py
            └── actors/
                ├── models.py
                └── ...
        

        python scripts/upload_files.py
        

        # 在Django shell中验证
        from actors.models import Actor
        actor = Actor.objects.get(name="张艺谋")
        print(actor.avatar.url)  # 输出: /media/portrait/张艺谋.jpg
        

        文件保存在 MEDIA_ROOT/upload_to/ 目录下,其中:

        • MEDIA_ROOT 在 settings.py 中定义
        • upload_to 在模型字段中定义

        在模板中使用:

        <img src="{{ actor.avatar.url }}" alt="{{ actor.name }}">
        

        确保在开发环境中配置了媒体文件服务。

        • 使用 uuid 生成唯一文件名
        • 添加模型ID作为前缀
        • 使用时间戳

        # 更新文件时自动删除旧文件
        def save(self, *args, **kwargs):
            if self.pk:  # 检查是否是更新操作
                old = Actor.objects.get(pk=self.pk)
                if old.avatar != self.avatar:  # 检查头像是否更改
                    old.avatar.delete(save=False)  # 删除旧文件
            super().save(*args, **kwargs)
        

        通过本教程,您学会了:

        1. 如何配置 Django 脚本环境
        2. 如何通过脚本上传文件到 ImageField
        3. 文件保存路径的处理机制
        4. 生产环境的最佳实践

        关键点:

        • 使用 file_field.save() 方法上传文件
        • 确保 MEDIA_ROOT 正确配置
        • 文件将自动保存到 MEDIA_ROOT/upload_to/ 目录
        • 数据库记录相对路径(相对于 MEDIA_ROOT

        通过实现这些技术,您可以轻松地通过脚本将文件上传到 Django 的 ImageField 字段,并确保文件保存在正确的位置。

        以上就是Django通过脚本上传文件的详细操作指南的详细内容,更多关于Django脚本上传文件的资料请关注风君子博客其它相关文章!

        您可能感兴趣的文章:

        • Django+simpleui实现文件上传预览功能(详细过程)
        • Python web实战教程之Django文件上传和处理详解
        • 使用Django+Vue编写一个文件上传器
        • Django+Vue实现文件上传下载的项目实践
        • vue与django(drf)实现文件上传下载功能全过程

        站内搜索