Setting FileField from UploadedFile

Hello, I’m stuck on something that should be fairly simple and can’t figure it out.

Basically, I have a model like this:

class Attachment(models.Model):
    report = models.ForeignKey(Report, on_delete=models.PROTECT)
    thefile = models.FileField()

and I want to create it from a multipart POST request like (pseudocode):

POST /upload-attachment
    report_id = 5
    thefile = (file content)

Now, it sounds like ModelForm classes can’t deal with raw IDs, so that’s a no-go.
I can use a normal Form or even get the data manually from the Request object.
But how would I set Attachment.thefile from request.FILES["thefile"]?

I’ve found the method FieldFile.save(name, content, save=True) but that seems to expect content to be a File instance.

Hi!

What do you mean by this?

Did you look at this part of the documentation?

Also, when you’re working with uploading files, you’ll want to review the File Uploads docs.

I meant that a models.ForeignKey is mapped to a forms.ModelChoiceField and that seemed to use some special values to select the model instance, however I now realize I have misinterpreted the documentation. Specifically, in ModelChoiceField.to_field_name:

<select id="id_field1" name="field1">
<option value="obj1.pk">Object1</option>
<option value="obj2.pk">Object2</option>
...
</select>

I thought “obj1.pk” was what would actually be generated, so I got the impression that it was some special format used by Django. Reading that again, I understand it’s just pseudocode and the actual code will use the object id:

<select id="id_field1" name="field1">
<option value="1">Object1</option>
<option value="2">Object2</option>
...
</select>

In other words, it looks exactly what I need. Thanks for pointing that out.

Looks like I missed something there too. From that doc, the manual way to do it seems to be:

instance = ModelWithFileField(file_field=request.FILES['file'])
instance.save()

Thanks for the hint. It’s what I wanted to know, although using a ModelForm is even easier than doing it manually.