This course will become read-only in the near future. Tell us at community.p2pu.org if that is a problem.

Modeling our database


For this task we will be setting up our database for a cooking recipe website (it got the most votes in our class project poll). 

In django, we create models for our database in the models.py file found in an application folder. For information about creating an app in our django project take a look through the documentation.

The process for setting up your database is typically:

  1. create an app
  2. create a Model class
  3. add the app to your settings.py and make sure you fill out the database settings
  4. go to the terminal and cd to your project folder
  5. type "python manage.py syncdb"
  6. type "python manage.py migrate" (assuming you are using south)

Using what we learned in mapping our systems and entity relationships, we are ready to create a simple database to power a recipe website. For this website we will have the following requirements:

  • Users must be able to create/edit/delete recipe
  • Recipe's can be sorted based on food type (ie American, French, Italian)
  • Recipe's can be sorted based on date uploaded
  • Users have a profile with first name, last name,  blurb about them, and food type specialty

Your Assignment

Read the about django models here: https://docs.djangoproject.com/en/1.3/topics/db/models/ 

Create an application called "recipes" in your django project. Create your models in the models.py file and post it here. I would recommend you create an entity relationship map so you can get your head around the models for this project. DO NOT SYNC THE DATABASE YET. 

Use this for reference on which fields to use: https://docs.djangoproject.com/en/1.3/ref/models/fields/#model-field-types

Task Discussion


  • Jessica Ledbetter   July 31, 2011, 2:13 a.m.

    class Recipe(models.Model):
        title = models.CharField(max_length=200)
        slug = models.SlugField(max_length=110)
        ingredients = models.TextField()
        instructions = models.TextField()
        creator = models.ForeignKey(User)
        food_type = models.ManyToManyField(FoodType)
        created_on = models.DateTimeField(
            auto_now_add=True, default=datetime.datetime.now)

     

    class User(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=30)
        username = models.CharField(max_length=255, default='', unique=True)
        email = models.EmailField(max_length=75, unique=True)
        password = models.CharField(max_length=255, default='')
        bio = models.TextField()
        food_type = models.ManyToManyField(FoodType)

     

    class FoodType(models.Model):
        title = models.CharField(max_length=100)
        slug = models.SlugField(max_length=110)

     

    Though I think I'm going to try a different way of logging in than storing a password. Maybe openid all that stuff.

  • Alex Kehayias   July 31, 2011, 10:34 a.m.
    In Reply To:   Jessica Ledbetter   July 31, 2011, 2:13 a.m.

    Very good! I would make the following suggestions though:

    • There is an existing User class in django that already has the basic first name last name email pass etc. It's used for the django auth system and can be called from any request by doing request.user. Since we are are adding a few more fields to it try creating a user profile http://www.turnkeylinux.org/blog/django-profile or simply create a model with additional fields and use a foreign key to the User class. To get to the User class: from django.contrib.auth.models import User
    • Slug fields are cool, but we don't necessarily need to store them. In my opinion you don't want to use a slug as a unique ID. Therefore you really don't need to store them. Check out the slugify() function built in to django from django.template.defaultfilters import slugify. We can contruct urls that have a slug in them, but the slug doesn't really mean anything to the url routing. Stackoverflow actually does that from what I remember. You can delete the slug and the url will still work. It's just good for SEO and user experience.

    The best way to go about testing this would be to add all the models you created to the admin, run the django dev server, and log into the admin to play around with creating objects. I'll explain more about that later today. 

  • Jessica Ledbetter   July 31, 2011, 12:56 p.m.
    In Reply To:   Alex Kehayias   July 31, 2011, 10:34 a.m.

    Thank you for the compliment and feedback :) I'll update my models accordingly!

    Lernanta stores the slug so that's interesting. Maybe time to refactor that too ;)

  • Alex Kehayias   July 31, 2011, 1:20 p.m.
    In Reply To:   Jessica Ledbetter   July 31, 2011, 12:56 p.m.

    It's more of a preference thing, but if you don't really need it then no need to store it I suppose. You can use the objects pk as a unique identifier or some random number or hash. We do that at BeanSprout also. 

  • Jessica Ledbetter   July 31, 2011, 5:59 p.m.
    In Reply To:   Alex Kehayias   July 31, 2011, 1:20 p.m.

    Ah! Gotcha. Thank you :)