Accelerating Information Technology Innovation http://aiti.mit.edu Rwanda Summer 2011 Django 01: Models Models • Suppose we want to create a web application to manage data about thousands of movies • What information would we want to store? – Title – Rating (scale from 1 to 5) – Genre – Lead Actor – Supporting Actors 2 Models • How would we think about storing this data? – Lecture 4: Dictionaries and lists are used to store data in Python • Web applications use databases – Lots of options varying syntax – Each table represents a different model – Each column is a different attribute • Django: Common interface to almost all database solutions (NoSQL and SQL) 3 Models • Django’s database interface works with any object of type django.db.models.Model • To create your own Model, use inheritance! from django.db import models class Movie(models.Model): # attributes go here Inherits from models.Model 4 Models • Models have attributes: Fields • We create ‘instances’ of Model objects in a different way (no __init__ function necessary) from django.db import models class Movie(models.Model): # attributes go here self.title = models.CharField(max_length=100) self.rating = models.IntegerField() Field to store text (strings and unicode objects) Field to store the rating the movie received 5 Models • Some attributes indicate special relationships to other Model objects • ForeignKey: OneToMany • ManyToManyField: Well, it’s a many-to-many field from django.db import models One movie can have many supporting actors; one supporting actor can be in many movies class Movie(models.Model): rating = models.IntegerField() title = models.CharField(max_length=100) genre = models.CharField() lead_actor = models.ForeignKey(Actor,related_name=‘lead actor’) support_actors = models.ManyToManyField(Actor,related_name=‘support’) One lead actor who could be the lead actor in other movies 6 Checkpoint: Models • Build a django Model class for Actor – What does the class inherit from? – What attributes should the class have? • Build a django Model class for Award – What does the class inherit from? – What attributes should the class have? 7 Checkpoint: Models • Actor Model class: class Actor(models.Model): name = models.CharField(max_length=100) birth_date = models.DateField() • Attributes • name: a string- use a CharField • birth_date: a datetime.date- use a DateField 8 Checkpoint: Models • What type of field should we use for the title of the Award? • CharField • What type of field should we use to denote the winning actor? • ForeignKey (one actor, many awards) • What type of field should we use for the nominees (each nominee is a Movie)? • ManyToManyField (each movie can be nominated for many awards, each award has many nominees) 9 Checkpoint: Models • Award Model class: • What type of field should we use for the title of the Award? • What type of field should we use to denote the winning actor? • What type of field should we use for the nominees (each nominee is a Movie)? class Award(models.Model): title = models.CharField(max_length=100) sponsor = models.CharField(max_length=100) year = models.DateField() winning_actor = models.ForeignKey(Actor) winning_movie = models.ForeignKey(Movie,related_name=‘winning movie’) nominees = models.ManyToManyField(Movie,related_name=‘nominees’) 10 Checkpoint: Models • Wait! How does Actor relate to the Movie class that we just wrote? • We only need to specify the relation in one of the models • Later: We can go “backwards” and get all Movie objects with the same lead actor or supporting actors class Actor(models.Model): name = models.CharField(max_length=100) birth_date = models.DateField() 11 Models • Inserting information into the database – Now: command line (manual) – Later: admin (Django GUI Interface) – Monday: forms (user-initiated) • But we need to actually create our database first… 12 Models: • Add the application with the relevant models to the list of INSTALLED_APPS • Specify the path to your new database • Validate your Model classes – django-admin.py validate • Create or update the models in our project – python manage.py syncdb • Later: reset the database (clear all information) – python manage.py reset app_name – We’ll see the utility of this later on… 13 Models: Python Shell • Use the Python shell to add information to the database – python manage.py shell gives us a Djangoready Python shell • Let’s put information about ‘Akeelah and the Bee’ in our database – Movie: Akeelah and the Bee – Actor: Keke Palmer – Award: Outstanding Actress (won by Keke) 14 Models: Python Shell from movie_app.models import Actor,Award,Movie import datetime Import the model classes we made keke = Actor(name=‘Keke Palmer’,birth_date=datetime.date(1993,8,26)) Looks like our usual initialization… but a little different keke.save() Saves a new entry in the Actor table of the database How could we create a new entry for the movie ‘Akeelah and the Bee’ 15 Models: Python Shell akeelah_bee = Movie(title=‘Akeelah and the Bee’,lead_actor=keke, genre=‘Drama’,rating=4) How do we store akeelah_award into our database? akeelah_bee.save() Create the award akeelah_bee We need to stop and save akeelah_bee before setting our supporting actor attributes ManyToManyField: convenient, useful, and a little ‘weird’ 16 Models: Field Values • We know how to add entries into the database with different attribute values • How do we restrict attribute values? – Set of choices – Validate using our own rules (consider the max_length=100 rule that we have set on some of the CharField objects) 17 Models: Field Values • Suppose we wanted to add a gender attribute to the Actor class – gender should be a character, either ‘M’ for ‘Male’ or ‘F’ for ‘Female’ • The set of choices is a tuple of individual choices • Each choice is its own tuple GENDER_CHOICES = ( (‘M’,’Male’),(‘F’,’Female’)) ‘M’ and ‘F’ are the allowed field values ‘Male’ and ‘Female’ are the human-readable ‘choices’ (what you will see in the admin dropdown menu…see the next lecture) 18 Models: Field Values • Restrict the movie rating to a number between 1 and 5 • Use an adjective to describe the quality of the movie RATING_CHOICES = ((1,'Terrible'),(2,'Bearable'),(3,'Okay'), (4,'Good'),(5,'Fantastic')) class Movie(models.Model): title = models.CharField(max_length=100) # some attributes here rating = models.IntegerField(choices=RATING_CHOICES) Set the choices option to the RATING_CHOICES tuple 19 Models: Access • Suppose our database has information on three movies: – “Dreamgirls” – “Akeelah and the Bee” – “Something New” • All of these movies featured 2007 “Best Actress” nominees (won by Keke Palmer from “Akeelah and the Bee”) 20 Models: Access • How do we access different subsets of these movies? • QuerySet: iterable structure with zero, one, or more table entries (model instances) >>> Movie.objects.all() [<Movie: Akeelah and the Bee>, <Movie: Dreamgirls>, <Movie: Something New>] Returns a QuerySet with all model instances >>> Movie.objects.filter(title="Dreamgirls") [<Movie: Dreamgirls>] Returns a QuerySet with model instances that have title ‘Dreamgirls’ 21 Models: Access • How do we access different subsets of these movies? • QuerySet: iterable structure with zero, one, or more table entries (model instances) >>> Movie.objects.filter(rating__lt=5) [<Movie: Akeelah and the Bee>, <Movie: Something New>] Returns a QuerySet with model instances that have rating less than 5 >>> Movie.objects.filter(rating=5) [<Movie: Dreamgirls>] Returns a QuerySet with model instances that have rating equal to 5 22 Models: Access • Access a particular Model instance: – Use the get command • Access to Model attributes: – Use the same .attribute syntax as in Python classes >>> dreamgirls = Movie.objects.get(title="Dreamgirls") >>> print dreamgirls.lead_actor Beyonce Knowles 23 Backup Slides • References: IMDB.com 24 Models: Using the Admin • admin is a builtin Django module • Simple GUI to create and modify the entries in your database models.py class Actor(models.Model): # some code class Award(models.Model): # some code class Movie(models.Model): # some code admin.site.register(Actor) admin.site.register(Award) admin.site.register(Movie) 25