Welcome back, everyone.
In this lecture, we're going to focus on a user specific page, almost like a user profile page that
only logged in user should be able to view their own specific profile, basically giving them authentication
and ownership over a single page.
To do this, we're going to add in some new attributes to one of our book instance classes or models.
That way, we can actually associate a book instance to a specific user, essentially checking out a
book, so to speak.
Let's do this inside our code.
All right, here I am, back inside our code editor in order to actually connect a book instance to
a user.
What I need to do is edit my models a little bit.
So recall if I go to models that pie and scroll down.
I have the book and then I have if I scroll down a book instance.
Remember, the book instance is a unique book that is a actual physical copy.
So it's not just something like Catcher in the Rye, it's actually copy number one of Catcher in the
Rye.
And there can be copy number two of Catcher in the Rye, etc..
So what would be nice is if I could associate a book instance to a specific user, especially if it's
checked out, then it makes sense.
So let's actually do this.
I'm going to add in a new class attribute called, let's say, borrower.
So bar is going to be equal to models dot.
And then we have to decide, is this a foreign key or is this something like a many to many relationship?
Well, if you think about it, a single book instance should only have a single borrower.
So this is more akin to a foreign key relationship because it's a one, two, one, really, a physical
copy of a book should only be able to be borrowed by one particular user.
So we're going to say foreign key relationship.
Now, the other thing to point out here is that how do we actually connect this to a user?
Well, we already know, based off our previous discussions and exploration of documentation, that
I can actually just import the user model.
So basically, in any that profile inside of Django, I can say from Django dot contrib dot off the
model's import user and that gives me access to the user model.
Notice it's not being used yet, so I need a scroll down here and pass it in as a foreign key relationship
that I have to decide what happens if you delete this.
So.
If I were to delete this particular user, then I was going to set it to NULL.
So I'll say sitting on.
And that means I need to say null is equal to true.
So it can't actually be Noel.
And we should also be able to leave this blank in case nobody has ever checked out this particular instance
of the book.
Now, remember, whenever you start updating your models that profile, you need to run migrations.
So that means I'm going to essentially kill what I have going on here.
And then we're going to say.
Python.
Let me clear this up.
So, Python.
Manage that pie.
Make migrations.
So we can see I added field borrower for the book instance and let's say Python.
Manage that pie migrate.
Okay, so it looks like everything worked well there.
If you got an error, you're going to want to check back and make sure you wrote this borrower line
correctly.
Essentially links a user as a foreign key to a specific book instance.
So now we should be able to do is visit her admin page and actually connect a particular book instance
to a user.
Eventually you would build out pages to make this all form based, so the user would go fill out a form
in this particular instance, etc. maybe a dropdown list, maybe a list view for all the book instances,
etc., using queries.
But right now we're going to do this the admin, so we don't make like a thousand pages here.
So we say Python manage that pie.
Run server.
And now our website is running.
All right.
So let me bring in our home page.
Something to note is you should be logged out before visiting the admin right now.
Basically, the admin is working with the user authentication system.
So if you visit the admin page but you're logged in, you'll get a warning from Django saying you're
already authenticated as another user.
Would you like to log in as someone else?
So let's go to forward slash admin here.
It's time to log in.
You have to use the credentials based off the super user you created.
I think I created one called my admin, so let me fill out those credentials.
If you forget this, you can always create another superuser at the command line.
And here we go.
So now I see authors, book instances, books, genres, languages.
I also see users.
So if we take a look at users, for example, I have the super users admin and my admin, and then I
also have my user and my user too.
Let's go with my user here and then they have the password active, etc..
User Permissions Important Dates.
Last Login Date Join.
But you notice right now I actually want to connect this user to a book instance.
So then I could come to book instances and I only have one book in my library.
So if you want you could add more instances.
But I have an instance here of super mystery, so let me click on this one and I'm going to select that
my user has borrowed it.
So now I could say, okay, it's on loan, so let's go ahead and save this.
So you'll notice right now that this particular book instance, essentially the only book inside our
library here, is being borrowed by my user.
So what I want to do is set up a page where my user can log in and then actually see the books that
they've checked out.
So that's all we need to do in the Django Admin page.
Obviously you could do this using forms and selecting model forms, etc. and have it be done on a page,
which is eventually what you want to create.
But for right now, we'll save those steps and just do it through the admin console.
I have faith in you that by the time you've reached this part of the course, you know how to do that
sort of thing, connecting models and making views for them.
So I'm just going to simply say, log out here and I've been logged out.
Click here to log in and I'm going to log in as my user.
My password.
I think it was one, two, three.
Here.
Perfect.
So now I'm logged in as my user.
What I want to do now is set up a template and view for actually doing a query and seeing, well, what
books do you have checked out?
So that's the final part of this little exercise here.
So I'm going to come back here.
And then let's go ahead and set that up.
So what I want to do is set up a template and also set up a view.
There's lots different ways we could do this, but it probably makes sense to use a generic list view
where I just run a query of book instances and actually filter them based off the user.
So there's different ways you could do this.
You could do a query based off the user and grab their books.
But I think it actually makes more sense to take advantage of the list view.
That way you can actually do it from a book instance perspective.
So that will actually make our life a little simpler as far as defining the view.
So we're to come back to views mixture at the top where you have create view and detail view that you
import list view.
So let's create this view.
And remember, I've also imported the log and required mixing.
So someone should have to be logged in to view this.
So we're gonna do the following, I'm going to say.
Class.
And we'll say checked out books, let's say, by user view.
So kind of a long name here.
You don't need to do it this long.
The login is required.
And I'm also going to inherit from list of you.
Okay.
So that means someone needs to be logged in to view this page.
That's exactly what I want.
I don't want to show them something else.
I just want to redirect them to the login page if they happen to check for their checked out books.
And I also want to make sure it's a list view, wireless view, because the point here is in general,
I'm just going to list all book instances, but I will filter.
Based off currently.
Logged in user session.
So how do I do this?
Well, I first thing to connect it to a model which already know is my book instance model.
So we have to make sure we imported that.
So come all the way to the top.
You'll notice from the models I have book instance imported here.
So that looks like it's good to go.
So I connected it to the model.
Then I need to connect it to the template name that I'll eventually create for this.
So we'll say catalog forward slash and let's actually just call this profile for each HTML.
We can decide on a better name for it later on.
And then if you want, depending on how many books you've created, you can also use page eight.
By what page rate means is how many pages or how many instances do you want to show per page?
So if I set this, for example, equal to five, that means I would show five book instances per page.
This is a super easy to use attribute in case you and the pooling a ton of records.
For example, if this person happens to have checked out 1000 books, we don't want a giant huge doom
scroll page, a thousand books and say it will say five books per page and they can keep doing their
pagination through that.
Okay.
Finally we have the actual query set.
So I want to override the default query set.
We talked about this a little bit in class based views, but for a list view, the default is just to
query every single book instance.
But I only want to do it for a specific user.
So we'll do the following.
We'll say the f get and it is query.
Set our overwrite method here and we're going to delete some of this code here.
So it's going to say get query set and then I have to return the actual query.
I want to be executed, which means I want to look up my book instance, models, objects, and then
I'm going to run a filter.
Where my filter is equal to where the borrower.
Is equal to make sure we spell that right.
So the borrower field is equal to self dot request, dot user.
So what's actually happening here?
Remember, each view has this request which is living inside the session and the user's actually inside
that request object.
Essentially all that means is when a person is logged in and they're able to reach this template profile
that HTML, then their request as they visit that page is going to have their user information.
So I can actually grab that here in order to filter, book, instance, objects, filter, etc. And
then if I want, I could order it by something.
And just for clarity, I like putting.
All here after that filter.
But if you want, you can just leave it blank as well and do something like quarter by, etc..
Okay.
So we have book instance objects, filter it based off where the borrower is equal to self that request
user.
Okay, so let's save that.
And finally, let's go ahead and connect it with a URL and a template.
So I'm going to come back to my URLs that py for catalog.
And we're going to say path.
Let's just say it's profile.
Forward slash and then this is views that and it's the kind of crazy name Chuck that books by user view
and then I just need to call it as a view.
There we go.
Name and let's make it profile.
So we'll save that.
Don't forget your commas as you add more things to your patterns.
And now let's create that profile.
Templates will say you file profile the HTML and this is where it's actually connected to the books.
So what can we do here?
Well, it's actually going to pass in a list.
So by default, remember the list view passes in something that is the name of the model like.
Book instance.
Let's make sure I spelled this right.
It's going to be something like book instance, the name of the model underscore list as a single underscore
there.
That is what's actually passed in using the query.
So it's model underscore list, which is the generic.
Let's pass then for list view.
If you didn't notice, this is the kind of thing I would look up in the documentation all the time.
So let's check it out.
I'm going to say.
Welcome to your profile.
Remember, it already has a log in required mixing, so I don't need to do anything of something like
check out the users authenticated here because recall in my views I'm already making sure that they
can only visit this page if they're logged in, which is nice.
That means I don't need to say if users authenticate or anything like that.
So we'll say welcome to your profile H2.
Here are your books checked out.
And then finally zooming in here a little bit so you can see this.
So welcome to your profile.
Here are your books checked out.
And then let's go ahead and say for make a full list here for book in.
And this is again, it's the name of the model lowercase book instance and then underscore list.
And then I can just create a little list here so we can do something like, um, or make a little paragraph
tag that gives the actual book.
So I could do something like that that actually just passes in the book.
Now I have to take a look at what our string representation is of an actual book.
So if we've got a model stop by a book instance, do we actually have a string?
It's just self ID, self book title.
Okay, I think that should be fine.
And obviously you could grab more information from that book object as we continued.
So let's see if we didn't commit any bugs, we should probably have maybe something like an L statement
that says, Hey, if this person doesn't have any books, it actually just instead of just saying,
Here are your books checked out blank, you'll say something like, You have no books borrowed, etc.
But it should be pretty okay given what we have here.
So I'm coming back to my home page.
I'm already logged in as my user in the admin.
I already set that up.
And so now what I'm going to do is go to catalog forward, slash profile, hit enter.
Now I see.
Welcome to your profile.
Here are your books.
Check out the unique I.D. and then super mystery.
So it looks like everything's working.
So what we did that's different in this particular lecture is I was able to actually log in as a user
and see a page that is hyper specific to me as my specific user.
And I don't need to worry about things like authentication.
That's actually happening on the template side because I'm making sure to do that on the view side.
Let me do a quick review of the steps we had to do to get here.
So step number one was I had actually established a relationship between one of my models and a user.
So whenever you're doing this sort of thing, there should be a relationship between the user and whatever
model you actually want to show.
That is for a foreign key connection.
If you just wanted to show that user information, like just a user profile page, then you technically
don't need to do what we did here.
You just directly grab that user class object.
So that's totally okay here.
Remember, it's easy enough to do.
You just had to import it and then you could just say, okay, I have a profile page.
It says welcome user dot name and we actually have showed you how to do that user, that username,
etc. We actually did that in the index page.
Next, what I had to do is come to views that pie.
And then as I mentioned, it's typically easier to think about this from the model perspective that
is not the user.
So we say something like, okay, think about book instances and then specify the query set to match
that user requirement.
This is typically the easier way to think about things.
I could have gone a different way and said something like Do a user and then try to do a search for
all their books so it would be like user and then grab all their book instances, etc. You can even
try a template based approach for something like that.
Just say book that checked out instances or whatever the user profile is.
But that kind of requires you to begin to set up your own custom user where they actually have attributes
associated for another model, which, given the way we could find it as a foreign key, it's easier
to think about it from the book instances perspective and just filter off of that.
So I'd recommend you do this approach as you continue your studies of Django, so to speak, and then
we set it up with a template name and we just had to look up in the documentation to remember, okay,
it's going to be the model underscore list for a generic list view and you can obviously continue to
edit this.
All right.
That's it for this lecture.
Thanks.