AttributeError: 'file' object has no attribute '_committed'
Asked Answered
H

3

8

I have a DjangoFileField in my model. I am trying to convert the type of the audio from that FielField to mp3 and then again trying to save it. But after converting the type and exporting it using pydub it is returning the following error

AttributeError: 'file' object has no attribute '_committed'

My code is like this

def get_from_function(AudioSegment, format):

    form = "from_{0}".format(format)
    print form
    if hasattr(AudioSegment, form):
        return getattr(AudioSegment, form)
    return None


    audio = request.FILES.get('audio', None)
    if audio:
        name_list = audio.name.rsplit(".")
        voice_format =name_list[1]
        from_format = get_from_function(AudioSegment, voice_format)
        if from_format and callable(from_format):
            sound = from_format(audio)
            audio = sound.export("media/{0}".format(name_list[0]), mp3")

when i print the audio it prints

<open file 'media/barsandtone', mode 'wb+' at 0x7f771e5e2f60>

and when i print the type of file it prints

<type 'file'>

but when i assign the audio field to django model like

Mymodel.objects.create(audio=audio)

it gives error

AttributeError at /create/
'file' object has no attribute '_committed'

What is the correct way to save the exported file into django model

Handwoven answered 13/4, 2016 at 21:45 Comment(0)
Q
7

django needs a ContentFile usually to do this passing it a stream of data, and it doesn't work the way you usually pass arguments to a model. The proper way to do this is the following

from django.core.files.base import ContentFile
[...]
mymodel = Mymodel()
mymodel.audio.save(audio.name, ContentFile(audio.read()))

don't forget to pass the stream to ContentFile. Django won't raise any errors if you pass it ContentFile(audio) but in that case you won't save the file content..

Queenstown answered 5/5, 2017 at 13:43 Comment(0)
E
6

I got same error that is solved now i would suggest you to open that file in read mode then save it. here is my code :

from django.core.files import File as DjangoFile
file_obj1 = DjangoFile(open(file_name, mode='rb'), name=file_name)
File.objects.create(title=file_name, file=file_obj1, content_object=task_obj, author=task_obj.client)
Espresso answered 1/5, 2020 at 17:38 Comment(0)
C
0

In my case I was creating a django form with some FileFields for which I wanted to show the currently existing file from a model's instance. I'm leaving this answer here in case anyone else end up here for similar reasons, even though I know that this answer doesn't apply to the OP's situation.

Normally you would bound the form and the model but in this case it's not possible for reasons a bit long to explain, so I wanted to query the model to obtain the File field and make it be the initial data.

It reached a point where I managed to make it work until the view can render the field and the currently existing field (as it's normally rendered by the ClearableFileInput widget).

That point was reached by filling self.fields["field_name"].initial with either:

  • Using a DummyFile class:
class DummyFile:
    def __init__(self, url, name):
        self.url = url
        self.name = name

    def __str__(self):
        return self.name
  • Filling it with the existing instance, like
self.fields[field_name].initial = doc.file.instance
self.fields[field_name].initial.url = doc.file.url

But then in both cases the AttributeError: 'file' object has no attribute '_committed' was raised when uploading a file, although it was correctly uploaded and saved.

Solution

Turned out that it behaves different when you assign the initial data for a field by using self.fields[field_name].initial than using self.initial[field_name], and doing it like this worked like a charm:

doc = Document.objects.filter(
    filters_to_locate_the_model_instance=this_and_that,
).first()
if doc:
    self.initial[field_name] = doc.file

The HTML is rendered with the link to the existing file, it loads fine if there is not an existing file, and uploads and saves a file without any error.

Candicecandid answered 8/10, 2021 at 16:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.