yeti logo icon
Close Icon
contact us
We'll reply within 24 hours.
Thank you! Your message has been received!
A yeti hand giving a thumb's up
Oops! Something went wrong while submitting the form.

The Basics of Django TastyPie and iOS RestKit

By
Tony Scherba
-
October 12, 2012

We've been using Django for the past couple years to build applications that communicate with mobile clients (that's kind of our thing).

This has always been our preferred backend because we are very concerned about the ability for our applications to scale and communicate across platforms. To make a long story short, being founded by two mobile developers, we've been on a quest since day one to discover the easiest and most effective way to make backend servers and apps play nicely together.

We went through a rather painful process of creating our own RESTful APIs with Django's view structure and while we were able to come up with some nifty results there was still a lot of repetitive glue code that we had to add. At PyCon 2012 we then discovered TastyPie and started using it's out of the box model creation for many of our API needs.

So as an example, we start with some Django models...

class State(BloodModel):
   name = models.CharField(max_length=30)
   abbrev = models.CharField(max_length=5)
   country = models.ForeignKey(Country)

   class Meta:
       unique_together = ('abbrev', 'country')

   def __str__(self):
       return self.name

class BloodCenter(BloodModel):
   name = models.CharField(max_length=255)
   pic = models.ImageField(upload_to='center_pics', blank = True, null=True)
   website = models.CharField(max_length=150, null=True, blank=True, help_text="Please use the following format: www.yourwebsite.com.")
   phone = models.CharField(max_length=20)
   address1 = models.CharField(max_length=100, verbose_name="Address 1")
   address2 = models.CharField(max_length=100, verbose_name="Address 2", blank=True)
   city = models.CharField(max_length=20)
   state = models.ForeignKey(State)
   zipcode = models.CharField(max_length=5)
   user = models.ForeignKey(User)
   latitude = models.FloatField()
   longitude = models.FloatField()

   class Meta:
       verbose_name = "Blood Center"

   def __str__(self):
       return self.name

class BloodType(BloodModel):
   name = models.CharField(max_length=5)
   description = models.TextField(null = True, blank=True)

   class Meta:
       verbose_name = "Blood Type"

   def __str__(self):
       return self.name

class BloodLevel(BloodModel):
   name = models.CharField(max_length=255)
   description = models.TextField(null = True, blank=True)
   image = models.ImageField(upload_to='blood_level', blank = True, null=True)

   class Meta:
       verbose_name = "Blood Level"

   def __str__(self):
       return self.name

class BloodEntry(BloodModel):
   blood_center = models.ForeignKey('BloodCenter')
   blood_type = models.ForeignKey('BloodType')
   blood_level = models.ForeignKey('BloodLevel')

   class Meta:
       verbose_name = "Blood Entry"
       verbose_name_plural = "Blood Entries"

   def __str__(self):
       return self.blood_center.name

TastyPie takes your models, serializes them and allows you to send them out. It also provides a framework for authentication which standardizes a huge piece of the puzzle. This was a big sticking point in our development prior to this because we would be producing for many platforms and coordinating authentication among developers was a big hassle. Adding TastyPie solved a huge part of our problem because we were able to create the API side of things rather easily but we still had the problem on the parsing end since we were now getting rather robust Django model data.


This is a sample of the type of data we're dealing with now...

{
address1: "270 Masonic Avenue  ",
address2: "",
city: "San Francisco",
created: "2012-06-13T12:54:45",
entries: [ ],
id: 14,
latitude: 37.77902,
longitude: -122.44712,
name: "Blood Systems Research Institute",
phone: " (415) 923-5771",
pic: null,
resource_uri: "/api/v1/blood_center/14/",
state: {
abbrev: "CA",
country: {
abbrev: "US",
created: "2012-05-01T00:00:00",
id: 1,
name: "United States",
resource_uri: ""
},
created: "2012-05-01T00:00:00",
id: 6,
name: "California",
resource_uri: ""
},
website: "www.bsrisf.com",
zipcode: "94118"
}

Makes complete sense but as you can see its a bit heavy if you need to write parsers to deal with this.

Pretty soon after starting with TastyPie, RestKit came onto our radar. As an iOS developer I saw RestKit as a great compliment to dealing with TastyPie data. In RestKit you set up amappingby telling it the objects being parsed, their relationships and attributes (we are now working wonders with this and RestKit's CoreData functionality). Having set up these relationships, when you use RestKit to call your API it will automagically parse and populate the applications memory with objects that look pretty darn close to your Django models.

And here's the mapping...

   RKObjectMapping* centerMapping = [RKObjectMapping mappingForClass:[BloodCenter class]];
   [centerMapping mapAttributes:@"address1", @"address2", @"city", @"name", @"phone", @"pic", @"website", @"latitude", @"longitude", @"zipcode", nil];
   
   RKObjectMapping* entryMapping = [RKObjectMapping mappingForClass:[BloodEntry class]];
   [entryMapping mapAttributes:@"date", nil];
   
   RKObjectMapping* stateMapping = [RKObjectMapping mappingForClass:[BloodState class]];
   [stateMapping mapAttributes:@"abbrev", nil];
   
   RKObjectMapping* levelMapping = [RKObjectMapping mappingForClass:[BloodLevel class]];
   [levelMapping mapAttributes:@"description", @"image", @"name", nil];
   
   RKObjectMapping* typeMapping = [RKObjectMapping mappingForClass:[BloodType class]];
   [typeMapping mapAttributes:@"description", @"name", nil];
   
   [entryMapping mapKeyPath:@"blood_level" toRelationship:@"blood_level" withMapping:levelMapping];
   [entryMapping mapKeyPath:@"blood_type" toRelationship:@"blood_type" withMapping:typeMapping];
   [centerMapping mapKeyPath:@"entries" toRelationship:@"entries" withMapping:entryMapping];
   [centerMapping mapKeyPath:@"state" toRelationship:@"state" withMapping:stateMapping];
   [[RKObjectManager sharedManager].mappingProvider setMapping:centerMapping forKeyPath:@"objects"];

Currently if you search TastyPie RestKit the only thing that comes up is a StackOverflow post about someone giving up on this stack. The TastyPie and RestKit stack most definitely works and we have a number of examples (four, in final stages of production) working beautifully. We'd love to field any developer questions (support@yetihq.com), we see this as a powerful stack we're excited to continue developing with in the future.

Tony Scherba is a CEO + Founding Partner at Yeti. Tony has been developing software since high school and has worked on digital products for global brands such as Google, MIT, Qualcomm, Hershey’s, Britney Spears and Harmon/Kardon. Tony’s writing about innovation and technology has been featured in Forbes, Huffington Post and Inc. At Yeti, Tony works on strategy, product design and day to day operations, hopping in and working with the development teams when needed. Follow Tony on Twitter.

You Might also like...

Busting 5 App Development Myths

The following are five pervasive myths about why app development should be a simple process — and the real reasons that a good product takes time.

Token-based Header Authentication for WebSockets behind Node.js

Using Node.JS to proxy requests to mutate them under the hood can be beneficial. In cases like these, it can also make your product more secure.

VIDEO: Building API's with Django and GraphQL

At our last Django Meetup Group event, Jayden Windle, the lead engineer at Jetpack, an on demand delivery company, talks building APIs with Django and GraphQL. Watch the video to learn more.

Browse all Blog Articles

Ready for your new product adventure?

Let's Get Started