Hey,
So I have this prototype where I save an object from a regular form view to my S3 bucket using S3Boto3:
class UploadFileView(FormView):
form_class = UploadFileForm
template_name = 'uploader/upload_cls.html'
success_url = 'myapp:index'
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, request.FILES)
if form.is_valid():
file = request.FILES["file"]
media_storage = MediaStorage()
saved_file = media_storage.save(f"testfile-{datetime.now()}", file)
return redirect(self.success_url)
return render(request, self.template_name, {'form':form})
class UploadFileForm(forms.Form):
file = forms.FileField()
class MediaStorage(S3Boto3Storage):
location=settings.AWS_MEDIA_LOCATION
That works fine and when picking a file from the uploader view, it gets saved to my S3 bucket. So I know that the whole settings.py / AWS setup is good, because I can upload & retrieve my documents this way.
Now I want to do the same with an inlineformset and I’m a little stuck.
The issue that I have is that the inlineformset itself works. However, the file itself is never saved to the S3 bucket. I’m guessing I should override a save() method somewhere to make that happen… But which one? The form’s? The model’s? Or iterate directly in the view’s post()? Here’s rough idea of the relevent code:
DocumentFormSet = inlineformset_factory(Produit, DocumentProduit,
form=DocumentsProduitForm,
extra=0,
can_delete=True)
class DocumentProduit(models.Model):
fk_produit = models.ForeignKey(Produit, on_delete=models.SET_DEFAULT,related_name="documents", null=False, blank=False, default=0)
document = models.FileField(verbose_name="Document Produit", blank=True, null=True)
filename = models.CharField(max_length=50, verbose_name="Nom du document", null=True, blank=True)
class DocumentsProduitForm(ModelForm):
class Meta:
model = DocumentProduit
fields = ["document", "filename"]
Saving the formsets is actually done via a mixin that I add to the cbv:
class FormFormsetValidationMixin:
def form_valid(self, form, formsets=[]):
self.object = form.save()
for fmset in formsets:
fmset.instance = self.object
fmset.save()
return self.object
So what currently happens is that my inlines are correctly saved (other formsets also use this same pipeline). I get no errors and the succes_url is rendered, however the S3 shows nothing.
Basically what I would like to achieve is a smart way to ensure my object is saved, ideally without iterating directly in the view’s post() methods to mess around with individual request.FILES objects. Any smart ideas?