text: Up to this point, we have been running without a database. This means that we have no reliable way to persist data on the server. Let’s look at how to set up a database to work with Django. This will allow us to persist data in our models and will finally get rid of this annoying error you have been seeing:
  You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them.
  Postgres is a popular SQL-based database. Another popular one you may have heard about is mySQl. They are pretty similar, but for not we will use postgres.
  You should have already installed postgres on your system in Week 1. Check to make sure Postgres is running by typing:
  psql
  If it says command not found, then you need to run these commands from Week 1 to install and start Postgres:
  brew install postgresql && brew services start postgresql # Note: type `brew tap homebrew/services` first if you do not have brew services
  If you get an error that says that it couldn’t connect to the server, you probably just need to start the server:
  brew services start postgresql
  Most likely you got the following error:
  psql: FATAL: database "
  " does not exist
  Here is why you get that error: the command
  psql is designed to bring you into a REPL that gives you access to one of your local databases (Your single postgres installation can host lots of DBs). By default, it assumes that you are trying to access a database that is named your username. For example, my username is
  Abe, so postgres looks for a database called
  Abe to give you access to.
  Well, we haven’t created any databases yet, so it has nothing to access. Create one now that is named that same as your username:
  createdb `whoami` # Note: `whoami` returns your username, you can try running it on its own to experiment
  Great, now run
  psql again.
  You should see something like this:
  psql (9.6.3) Type "help" for help.
  =#
  This means that we are inside your Postgres REPL for the database named after your username. We can do lots of stuff in here, like create tables, add rows, delete things, etc. But for now, let’s practice the most important command (exiting the REPL). You may be inclined to try
  <control> C or
  exit. These won’t work. Here is the command that gets you back out:
  \q
  Now you should be back into your standard terminal.
  In order for Django to access postgres, you will need to set up two things:
  Let’s set this up with the following commands. For this practice, we’ll be creating a new Django App called “djangowithpostgres”, so let’s use that name for our database and db user as well:
  # Enter the postgres REPL psql # Create a DB for your new Django app to use # NOTE: All lines in the postgres REPL must end with a semicolon CREATE DATABASE django_with_postgres; # Create a user for your app to use and assign it a password CREATE USER django_with_postgres_user WITH PASSWORD 'myPassword'; # Give the user you just created access to all actions on your postgres DB: GRANT ALL PRIVILEGES ON DATABASE django_with_postgres TO django_with_postgres_user; # Exit \q
  Let’s create a new Django project that we will use to experience with models, migrations, and postgres.
  # Move to your projects directory cd ~/projects # Create a new django project called `django_with_postgres` django-admin startproject django_with_postgres cd django_with_postgres # # Create a requirements.txt file to track our dependencies touch requirements.txt # Write all currently installed packages to our requirements.txt file pip freeze > requirements.txt
  Make sure your new app runs, debug any errors if not
  python manage.py runserver
  Postgres requires a special package to work, install it and add it to
  requirements.txt
  pip install psycopg2 pip freeze > requirements.txt
  Alter the Django config to use postgres instead of sqlite. Change the
  DATABASES section of
  settings.py to include the details needed for postgres.
  NAMEshould be the name of the database you created earlier (I called it
  django_with_postgres)
  USERshould be the user you gave access to the database (I used
  django_with_postgress_user)
  PASSWORDshould be the password you set earlier (I used
  myPassword)
  Note that for a real project, you should keep things like passwords using a safer method.
  DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'django_with_postgres', 'USER': 'django_with_postgres_user', 'PASSWORD': 'myPassword', 'HOST': 'localhost', 'PORT': '5432', } }
  Let’s test out our database connection by creating and running our base migrations. Migrations are files that tell your database what SQL commands it should run to set it up in the way you intend to use it. Luckily, Django takes care of creating these for us based on how we design the model structure. As you have seen by the following error whenever you start the server, there are already some outstanding migrations that need to be run:
  You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them.
  We haven’t made any models yet, but Django has some built in models and configurations that it stores in the database. For these, it has already created the migrations, but we need to run them. Even though Django has already created these migrations we will still run through both vital steps for migrations:
  run migrations (Django applies all of the migration files that have not yet been run to you postgres database)
  # Make the migrations. Since we haven't created any models yet, you will see "No changes detected" python manage.py makemigrations
  python manage.py migrate
  Now that we have postgres set up, let's add our first model. Django models are just like python models, they can have associated attributes and functions. For now we'll just focus on the attributes. The attributes will actually become items that are saved into the database. We'll create a few simple models that we designed earlier when we talked about database schemas. Table Name: Owner column role id primary key name attribute age attribute address foreign key Table Name: Pet column role id primary key name attribute breed attribute owner foreign key Table Name: Address column role id primary key street_address attribute zipcode attribute state attribute Let's create a new "apps" (directory) at the root of the project to hold the apps (subsections) of this django projects. Then, let's create a diretory called `animal_tracker`. To represent these models in code, create a folder called `models` inside the `animal_tracker` directory. At each level, we'll make sure to create an `__init__.py` so that Django sees them.
  mkdir apps touch apps/init.py mkdir apps/animaltracker touch apps/animaltracker/init.py mkdir apps/animal_tracker/models
  Now, create a file for each of the models we want to represent. Also, create the `__init__.py` so that Django knows about this directory
  cd apps/animal_tracker/models touch init.py touch owner.py touch pet.py touch address.py cd ../../..
  Next, we need to add the attributes for each model so that Django knows what the database tables should look like. :green-check-mark: Read about how Django Models work: * [Django Models]( There are few key things that you need to do when writing models files: * Inherit from the Django base model class at `django.db.models` * Choose the appropriate field type for each attribute (`CharField`, `IntegerField`, etc.) and add any needed additional information (default value, character length, etc.) * Make any linkages (One-to-One, One-to-Many, Many-to-Many) If you are feeling brave, read through the documentation on Django models and try to create the models files to represent the three tables above. Note that it is also helpful to import all of your model files in the the `__init__.py` file. This will make it so that when you want to import one of your models into a file somewhere else in your project you can import them in a concise manner:
  from djangowithpostgres.models import Owner, Pet, Address
  from djangowithpostgres.models.owner import Owner from djangowithpostgres.models.pet import Pet from djangowithpostgres.models.address import Address
  Here are my solutions: #### __init__.py
  from .owner import Owner from .pet import Pet from .address import Address
  #### owner.py
  from django.db import models from apps.animal_tracker.models import Address
  class Owner(models.Model): name = models.CharField(max_length=128, null=True) age = models.IntegerField(null=True) address = models.ForeignKey(Address)
  #### pet.py
  from django.db import models from apps.animal_tracker.models import Owner
  class Pet(models.Model): name = models.CharField(maxlength=128) breed = models.CharField(maxlength=128) owner = models.ForeignKey(Owner, related_name=‘pets’)
  #### address.py
  from django.db import models
  class Address(models.Model): streetaddress = models.CharField(maxlength=256) zipcode = models.CharField(maxlength=5) state = models.CharField(maxlength=2)
  Make your files look like this (or try your own version if you want) and run:
  python manage.py makemigrations
  It probably says:
  No changes detected
  Ah, man! We just made a bunch of changes to our models files but Django doesn't seem to see them. Why not? Well, we never added this new app to our `settings.py`, so Django doesn't know about it. Do that now:
  …
  INSTALLED_APPS = [ ‘django.contrib.admin’, ‘django.contrib.auth’, ‘django.contrib.contenttypes’, ‘django.contrib.sessions’, ‘django.contrib.messages’, ‘django.contrib.staticfiles’,
  'apps.animal_tracker',
  ]
  …
  Now run `python manage.py makemigrations` again. It likely still says `No Changes Detected`. This is because it is the first time we are running migrations on the `animal_tracker` app. The first time, we need to specify the name of the app after the `makemigrations` command:
  python manage.py makemigrations animal_tracker
  Now, you should see the successful operation:
  Migrations for ‘animaltracker’: apps/animaltracker/migrations/0001_initial.py - Create model Address - Create model Owner - Create model Pet
  Next, we need to apply the migrations:
  python manage.py migrate
  Great, so now our DB should reflect the model structure in our app. Let's test it out. To test it, we will make use of Django's build in `shell` command. This puts you into a python REPL but it also loads all of the Django models and configuration so that you can access your application programmatically through the command line. It is great for testing models and connections. Open the Django Shell:
  python manage.py shell
  Now we are in a python REPL. We want to test out our models. To do so, we need to import them into the REPL session.
  from apps.animal_tracker.models import *
  Now we can do several commands to test that our models are working:
  addressinstance = Address.objects.create(streetaddress=‘123 Main St’, zipcode=‘99231’, state=‘CA’)
  99231
  address_instance.zipcode
  Address.objects.all()
  null=True
  addressinstance2 = Address.objects.create(street_address=‘Other Address’, zipcode=‘11111’, state=‘NY’)
  Address.objects.all()
  Address.objects.filter(zipcode=‘11111’)
  address_instance
  owner = Owner.objects.create(name=‘Abe’, age=27, address=address_instance)
  Owner.objects.all()
  pet = Pet.objects.create(name=‘Charlie’, breed=‘Poodle’, owner=owner)
  owner.pets.all() owner.address
  exit()