В Django сохраняйте несколько имен файлов (НЕ файлов) для нескольких полей FileFields
В Django
я хотел бы сохранить несколько имен файлов ( НЕ файлы) для нескольких FileFields
в Model
.
У меня есть:
- 2
Model
s: Один для храненияFileField
s для различных типов файлов (для каждого типа файлов представляется одинаковое количество файлов); другой для хранения соответствующей информации о файлах. - 2
ModelForm
s: По одному для каждого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
и т.д. я бы тоже хотел знать. Буду признателен за любую помощь.