user2143729
user2143729

Reputation: 21

Django REST framework and Backbone.js File Upload problems

I'm trying to upload an image file with backbone.js and JQuery to a API made by Django REST Framework. I've started by following this tutorial http://10kblogger.wordpress.com/2012/05/25/a-restful-password-locker-with-django-and-backbone-js/.

When I go to submit the form and upload the file I get a bad request saying the photo field is required, even though I have chosen a file.

The error I get is:

{"photo":["Thisfieldisrequired."]}

and also:

The requested URL /static/media/C:/fakepath/music notes.png was not found on this server.

my HTML:

<div id="listingModal" class="modal hide fade">
    <form id="listingForm" enctype="multipart/form-data" method="post">
        <div class="modal-header"><button class="close" data-dismiss="modal">×</button>
            <h3>Listing Details</h3>
        </div>
        <div class="modal-body">{{ form }}</div>
        <div class="modal-footer">
            <a class="btn" href="#" data-dismiss="modal">Cancel</a>
            <input class="btn btn-primary" type="submit" value="Save" />
        </div>
   </form>
</div>

The saving function:

handleModal: function(event) 
    {
        event.preventDefault();
        event.stopImmediatePropagation();
        var form = $('#listingForm');

        var listingData = 
        {
            title: $(form).find('#id_title').val(),
            description: $(form).find('#id_description').val(),
            //user: $(form).find('#id_user').val(),
            photo: $(form).find('#id_photo').val(),
            trade_completed: $(form).find('#id_trade_completed').val(),
            date_created: $(form).find('#id_date_created').val(),
            date_completed: $(form).find('#id_date_completed').val(),
        };

        if($('#listingModal').data('client_id'))
        {
            listingData.listing_id = $('#listingModal').data('client_id');
            this.listings.updateListing(listingData);
        }
        else
        {
            this.listings.addNew(listingData);
        }
            //hide the modal
        $('#listingModal').modal('hide');

        return this;

    },

The updateListing function:

updateListing: function(listingData)
    {
        var listing = this.listings.get({id: listingData.listing_id});
        if(_.isObject(listing))
        {
            //iterate through the data, and add it to the model
            for(var key in listingData)
            {
                //dont copy id, already checked
                if(key != 'listing_id')
                {
                    listing.set(key,listingData[key]);
                }
            }
            listing.save();
            //this.listings.sort();
        }
    },

I've read some things saying It might be because I have to manually upload the file but am not sure on how to do that. Any help would be greatly appreciated.

EDIT: here is my settings.py media urls and static urls prove it's all set up right

MEDIA_ROOT = '/opt/bitnami/apps/django/django_projects/Project/Project/static/media/'
MEDIA_URL = '/static/media/'
STATIC_ROOT = '/opt/bitnami/apps/django/django_projects/Project/Project/static'
STATIC_URL = '/static/static_files_dir'

Also, the field in particular is called photo and is and Imagefield in the model.

Upvotes: 2

Views: 1455

Answers (1)

Steve Brownlee
Steve Brownlee

Reputation: 113

Not sure if you ever found a solution for this since it's been a few months, but I thought I'd respond in case anyone else stumbles around this issue.

Uploading files to a REST API resource URI requires special care as it is more complex than simply doing an HTTP POST with some standard (non file) form fields. However, HTML5 has made it far easier than it used to be.

If you look at your statement...

photo: $(form).find('#id_photo').val(),

That does not get the actual file. It grabs a temporary string that a browser's field field implementation puts there. In your case, it was C:/fakepath/music notes.png.

You need to get a reference to the actual files key on the control. For some sample code for use with jQuery, read How can I upload files asynchronously?

If you want to hand roll your own upload function, then read http://www.html5rocks.com/en/tutorials/file/xhr2/#toc-send-formdata

Upvotes: 2

Related Questions