You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django自定义文件存储系统增量编号格式异常问题求助

Fixing Duplicate File Naming with Incrementing Numbers in Your Custom Storage System

Looks like the issue comes from how you're extracting and incrementing the file number—your current logic keeps appending new numbers to the existing filename instead of replacing the old increment value. Let's break down what's wrong and fix it:

What's Causing the Broken Naming?

  1. Fragile Fixed Index: Using filename.split('_')[19] is super unreliable. The number of underscores in your filename won't always be 20, so this will either throw an index error or pull the wrong value entirely.
  2. Incorrect Root Filename Handling: When you process an existing file like nameofthefile_1.txt, you're treating nameofthefile_1 as the new file root. Then you add 2 to it, creating nameofthefile_1_2.txt—and this pattern repeats every time, leading to the nested numbers you're seeing.
  3. No Loop for Edge Cases: If a file gets deleted (e.g., nameofthefile_2.txt is removed), your current code would skip straight to 3 instead of filling the gap (though this is a minor point compared to the main issue).

Corrected Implementation

Here's a revised version of your CustomStorage class that properly handles incrementing numbers without nesting them:

import os
import re
from django.core.files.storage import FileSystemStorage

class CustomStorage(FileSystemStorage):
    def get_available_name(self, filename, max_length=None):
        # Split the filename into directory, root, and extension
        dir_name, file_name = os.path.split(filename)
        file_root, file_ext = os.path.splitext(file_name)

        # Extract the base name and current increment number
        # Match the trailing "_数字" pattern using regex
        num_match = re.search(r'_(\d+)$', file_root)
        if num_match:
            base_name = file_root[:num_match.start()]
            current_num = int(num_match.group(1))
        else:
            # Fallback: if no number suffix exists (though your initial filename has _1)
            base_name = file_root
            current_num = 0

        # Loop until we find a filename that doesn't exist
        while self.exists(os.path.join(dir_name, f"{base_name}_{current_num}{file_ext}")):
            current_num += 1

        # Build and return the final available filename
        new_filename = f"{base_name}_{current_num}{file_ext}"
        return os.path.join(dir_name, new_filename) if dir_name else new_filename

def user_directory_path(instance, filename):
    extension = filename.split('.')[-1]
    filename = f"file_{instance.identification}_1.{extension}"
    return f'folder/{instance.user}/{filename}'

How This Works

  1. Regex for Reliable Number Extraction: The regex r'_(\d+)$' looks for a number at the end of the filename root (after an underscore). This safely pulls the increment value regardless of how many other underscores are in the filename.
  2. Proper Base Name Separation: We separate the core filename (e.g., file_xxx from file_xxx_1) so we can replace the increment number instead of appending to it.
  3. Loop to Ensure Availability: The while loop checks if the generated filename exists, incrementing the number until it finds one that's free. This handles edge cases like deleted files or manually added versions.

With this code, uploading duplicates will generate filenames like file_xxx_1.txt, file_xxx_2.txt, file_xxx_3.txt exactly as you expected.

内容的提问来源于stack exchange,提问作者Kome Gognome

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 00:38:14