Ed Lynch Ed Lynch - 4 months ago 23
Python Question

Use CharField as a string

I want to create a model where I just put in two fields and the rest is generated with API requests, the generation I've got but I can't get the CharField in a usable string format.
So on field is:

name = models.CharField(max_length=250, default='default')

And I want to run it through:

name = self.name.replace(' ', '+')
movieData = (json.loads(str(urllib2.urlopen('http://www.omdbapi.com/?t=' + name + '&y=&plot=short&r=json').read(),'utf-8')))
movieYear = movieData.get('Year')

Saving movieYear as a field.
Thanks in advance


I think a custom save will help you accomplish what you are looking to do. Here's an example:

class MyModel(models.Model):
    name = models.CharField(max_length=250, default='default')
    movieData = models.JSONField(blank=True)
    movieYear = models.CharField(max_length=250, blank=True)

    def save(self, *args, **kwargs):
        url = 'http://www.omdbapi.com/?t={}&y=&plot=short&r=json'.format(self.name.replace(' ', '+'))
        data = json.loads(str(urllib2.urlopen(url).read(),'utf-8'))
        self.movieData = data 
        self.movieYear = data['Year']
        super(MyModel, self).save(*args, **kwargs)

This will let you make a request to a URL crafted from the self.name attribute (replacing spaces with +), then store the response in the fields you wanted.

If you use this solution, you will want to take care to include some kind of error handling - what happens if an invalid name is supplied? Or the returned data doesn't have a Year key for some reason? Or maybe the API is just down for a few minutes, so your valid request receives no response?

This will also make a request to that API on every save, which may have consequences for the speed of your application. You can force logic in a custom save to execute only when creating a new instance by using if self.pk is None.