В Django сохраняйте несколько имен файлов (НЕ файлов) для нескольких полей FileFields

В Django я хотел бы сохранить несколько имен файлов ( НЕ файлы) для нескольких FileFields в Model.

У меня есть:

  • 2 Models: Один для хранения FileFields для различных типов файлов (для каждого типа файлов представляется одинаковое количество файлов); другой для хранения соответствующей информации о файлах.
  • 2 ModelForms: По одному для каждого Model.
  • 1 представление: Для обработки логики получения имен файлов и их сохранения, и отбрасывания фактического файла.

Я просмотрел много вопросов Stack Overflow и вывел что-то, что приближает меня, но неправильно. В localhost:8000/admin/ я вижу, что моя неудачная попытка дает мне запись для каждого загруженного файла, НО каждая запись имеет одинаковые данные (имя последнего файла в списке для каждого поля).

models.py
from django.db import models
from decimal import Decimal
from django.core.validators import FileExtensionValidator

# Model for storing related info
class RelatedInfo(models.Model):
    info_name = models.CharField("Name", max_length=255)
    some_value =  models.DecimalField(
        default=Decimal(0.1), decimal_places=2, max_digits=5
    )
    X_path = models.CharField(max_length=255, null=True)
    Y_path = models.CharField(max_length=255, null=True)
    # Additional fields...

# Model for storing filenames
class FilesModel(models.Model):
    related_info = models.ForeignKey(
        RelatedInfo, on_delete=models.CASCADE
    )
    X_name = models.CharField(max_length=255, blank=True, null=True)
    X_file = models.FileField(
        null=True, validators=[FileExtensionValidator(allowed_extensions=["txt"])]
    )
    Y_name = models.CharField(max_length=255, blank=True, null=True)
    Y_file = models.FileField(
        null=True, validators=[FileExtensionValidator(allowed_extensions=["csv"])]
    )

forms.py
from Django import forms
from .models import RelatedInfo, FilesModel

class FilesForm(forms.ModelForm):
    # Initially as I didn't want the files, just the names, 
    # I had the FileFields in the form and not in the model.
    # But my current best failed attempt uses them in the model.

    # X_file = forms.FileField(
    #     # null=True,
    #     validators=[FileExtensionValidator(allowed_extensions=["txt"])],
    #     widget=forms.ClearableFileInput(attrs={"multiple": True}),
    # )
    # Y_file = forms.FileField(
    #     # null=True,
    #     validators=[FileExtensionValidator(allowed_extensions=["csv"])],
    #     widget=forms.ClearableFileInput(attrs={"multiple": True}),
    # )

    class Meta:
        model = FilesModel
        fields = ["X_file", "Y_file"]
        widgets = {
            "X_file": forms.ClearableFileInput(attrs={"multiple": True}),
            "Y_file": forms.ClearableFileInput(attrs={"multiple": True}),
        }


class RelatedInfoForm(forms.ModelForm):
    class Meta:
        model = RelatedInfo
        fields = "__all__"
views.py
from django.contrib import messages
from django.shortcuts import redirect, render
from .forms import FilesForm, RelatedInfoForm
from .models import FilesModel, RelatedInfo


def FilesView(request):
    if request. Method == "POST":
        # Get forms
        info_form = RelatedInfoForm(request. POST)
        files_form = FilesForm(request. POST, request.FILES)
        # Get files list
        X_files = request.FILES.getlist("X_file")
        Y_files = request.FILES.getlist("Y_file")
        # Form validation
        if info_form.is_valid() and files_form.is_valid():
            info_form_instance = info_form.save(commit=False)
            # I'm not doing anything here, it's in case I want to later on        
            info_form_instance.save()
            # Save multiple files
            for (xf, yf) in zip(X_files, Y_files):
                files_instance = FilesModel(
                    X_name=request.FILES["X_file"].name,
                    X_file=None,
                    Y_name=request.FILES["Y_file"].name,
                    Y_file=None,
                    related_info=info_form_instance,
                
                )
                files_instance.save()

            messages.info(
                request, f"Created: {info_form_instance.info_name}"
            )
            return redirect("/")
    else:
        info_form = RelatedInfoForm()
        files_form = FilesForm()

    context = {
        "files_form": files_form,
        "info_form": info_form,
    }
    template_name = "app/new_form.html"

    return render(request, template_name, context)

Критически, поскольку файлы большие, я даже не хочу "загружать" их вообще, просто возьмите имена и передайте их обратно для хранения. Если есть более чистый способ сделать это, используя generic Views и т.д. я бы тоже хотел знать. Буду признателен за любую помощь.

Вернуться на верх