One-to-Many Relations
Back for more? Perfect! Part 4 of Cat Collector will take us through setting up a one-to-many
(or 1:m) relationship in our database. Right now we have a bunch of cats and we can perform all basic CRUD functions on the cats. But since this is Cat Collector we really need to associate cats to their collectors, or users. Each single user will be able to have many cats in their collection, and this is what defines this as a one to many relationship: one user to many cats.
Let's Get a User!
In main_app/models.py
, let's include Django's built-in User model from their auth library:
We will use this user
again later when we implement the ability to log in. This user will have an ID and we will use that to link the user to their cats. This means that we need to add the user_id
to the Cat
model so that we know which user each Cat belongs to. Because this is a key from another table, we call it a foreign key
when we reference it from our Cat
model. The foreign key in the Cat
model connects to a user's ID which is the primary key
in the User
model. This connection of primary key to foreign key creates the relationship and because a cat can only ever have one collector it makes a one to many
relationship.
We should now run the python3 manage.py makemigrations
command to integrate our foreign key. We will get a prompt from Django asking for one of two options. You should see something like this:
Let's choose option 1.
This will create a 'dummy' field of User that will be populated with null value row for us. We want this.
It will ask you one more time to enter a default value:
Go ahead and enter the number 1
. This will set a row to simply 1
. This will then trigger a migration file creation called XXXX_cat_user.py
. Excellent!
Now run the migration by running
Play with our Admin view and bask in the joy of being able to create Users and assigning Users to Cats! Make that assignment for all of your Cats.
Our cats are not being associated with users by default. Later when we implement authentication this will happen based on who is logged in. We can update our view function now, however, to make this complete.
Go to your main_app/views.py
file and modify the class CatCreate
view:
Also make sure to add this line up at the top:
Okay, what is this? We added a form_valid()
function that will fire after Django validates the form. Inside this function we are saving the form without committing it to the database, we are adding the current user's ID onto that saved data, then we are saving it to the database, then we redirect to the cat list.
Create the User Profile URL
All the model code is in place but we can't really see any of this outside of the admin interface, which is nice for us but isn't very useful for our users. We should add a route to view one user, like a user profile page.
This will repeat the same pattern of:
Set up a URL in
urls.py
Create a view in
views.py
Make an HTML template in
/templates
Let's go to our main_app/urls.py
folder and update our urlpatterns
:
The stuff in the angle brackets lets us grab a passed-in username and store it in a variable called username
. Lets add to our main_app/views.py
file:
Lastly, we create a profile.html
template to show a single User and all of the Cats they have collected:
Let's also update our cats/index.html
page to allow us to inspect each user:
Last updated