Track data editing finally added to Djukebox
by Justin Michalicek on May 28, 2013, 2 a.m. UTCI finally got done adding track editing data to Djukebox. I can't remember when I started on this, but I believe it was well over 6 months ago. I had a lot of delays and not much free time in getting it done. I took two calculus classes, had my employer shut down all in house software development and lay off the entire team and so had to find a new job, and had a baby. It's been a long time coming, but the functionality is finally added.
I learned some things while adding the new features. I learned about some really cool features of [tastypie][1], such as PATCH request support and being able to PATCH, PUT, or POST to a resource and also modify or add related resources all in one request. I got to dig into the inner workings and learn a bit more about the hydrate/dehydrate cycle, adding extra resource URIs, and adding functionality like being able to toggle whether the API returns full foreign key data or just URIs to foreign keys.
Unfortunately I've also discovered shortcomings with tastypie. Mostly that it's pretty set in its ways and if you want to do something that hasn't been thought of, it can be a lot of trouble. I may end up having to move onto a different, more flexible framework or just handle my own REST API stuff. Tastypie is great for getting up and running quickly and does what it does very well, so if it works for you, then I'd recommend using it. I have just found that it will take quite a bit of tinkering to get it to work exactly like I need, and possibly never will. This is the price you pay with any framework, of course, so I'm not bashing Tastypie, it just may not be what I need now.
To add the editing functionality I tried a lot of things. I eventually ended up with a giant mess of JavaScript making AJAX calls back to the API, many of which had to be done in series rather than parallel, slowing things down and making it painful to edit and maintain. I had to see if an album existed in one request, if not, then I had to see if the correct artist for that album already existed in another, then if not I had to create the artist, then create the album, then tied the track to the new album. Then I had to go through roughly the same procedure for the track title and artist. I kept rewriting things, trying to make it less of a mess and find ways to make more requests in parallel. Unfortunately there was just no fixing it with that method.
What I ended up doing was adding a new resource to the API. This time rather than being a ModelResource which ties directly back to a Model, it's just a plain old Resource. It ties back to the Track model, the same as the TrackResource resource on the API does, but it only supports PATCH requests, and rather than modifying the track directly it handles all of the previous logic of finding and/or creating artists, albums, etc. Now it happens in one HTTP request which takes just milliseconds and happens in just a few lines of easy to read Python rather than being multiple HTTP requests, which could take a very long time, and being a jumbled, hard to read mess of JavaScript and jQuery Deferred objects.
Now I have to go figure out what bugs I've introduced by adding a new ability to edit data that wasn't previously editable.