Heads up! To view this whole video, sign in with your Courses Plus account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Django's class-based views are build on a _lot_ of methods. These methods provide the easiest way to customize your views.
If you've looked around on CCBV, you've no doubt seen the sheer gigantic number of methods that are available in your class-based views. Digging into these will open up a huge number of possibilities for you for customizing your views and getting just exactly the output that you want.
[MUSIC]
[SOUND] Welcome back to
0:05
Django Class-based Views.
0:05
So far in this course, you've learned
about several handy classes that Django
0:06
provides for you to make views from.
0:10
But all of these views end
up needing special bits and
0:12
pieces of code to make them
do exactly what you need.
0:15
You've already taken control of
the get_context_data method, but
0:18
there are many other methods for
customizing these views.
0:21
So join me in Workspaces and
see how to make these classes work for
0:24
you even harder.
0:27
So a lot of times, you need to have
a view that shows a group of items,
0:29
so like a DetailView or a ListView.
0:33
But you want it to only show items
that appear in a particular queryset.
0:36
You can override the queryset attribute,
which is just like queryset = whatever,
0:40
but you have to be very careful with
that because querysets are mutable.
0:45
So you have to be sure to
call .all at the end so
0:50
that it will actually go and
fetch this fresh queryset, or
0:55
you have to do what I'm gonna do, which
is to override the get_queryset method.
0:59
Either of these steps will let
Django correctly clone the queryset
1:04
before it actually processes the view.
1:08
And without that,
you get views that will show the same data
1:10
even though they should be
showing different data.
1:13
It gets messy because of how
the instantiation works.
1:17
So, I don't want anyone to delete a team
1:20
unless they're the coach of the team or
they're a superuser.
1:24
So the DeleteView,
like a lot of other views,
1:29
has this get_queryset method that,
well, gets the queryset.
1:33
The queryset is a collection of data,
even if it's only showing one item like
1:40
the DeleteView or the DetailView does, the
view gets a queryset of items and then,
1:44
from that queryset, takes a single item.
1:49
So, that way,
in controlling the queryset in general,
1:52
you control the pool of possible choices.
1:56
So this is generally the one
that you wanna override.
1:59
So it's a pretty basic method.
2:03
It just takes one argument, which is self.
2:07
And then, inside of here, I'm gonna
check to see if the request object,
2:09
which is the request that comes into the
view, if the user on that is a superuser.
2:16
So if not self.request.user.is_superuser,
then I'm gonna return
2:24
self.model.objects.filter(coach=self.requ-
est.user).
2:29
Otherwise, if that if
doesn't actually happen,
2:38
I'm just gonna return
self.model.objects.all.
2:41
So, all class-based views have a request
attribute on themselves, that is,
2:44
the request for the view.
2:49
You can use that to get to the current
user and all sorts of other things.
2:51
Here, like I said, I'm checking to
see if the user is a superuser.
2:55
And if they're not,
2:58
then I'll filter down the list of teams
to only the teams that they coach.
2:59
I could use the reverse
foreign key from the user.
3:02
That feels weird compared to using
the model that's already associated
3:06
with the view.
3:09
If they are a superuser, though, then I'll
just return all of the teams that exist.
3:10
So, that means I need to make
another user and a team for them.
3:14
So, copy this over, go to admin.
3:22
Let's add another user.
3:26
So this will be testuser Test password,
test password.
3:30
And then I want them to be able to log in,
so
3:37
I'm gonna come check this Staff status,
but
3:41
I do not want them to be a superuser.
3:45
So save that user.
3:49
Hop back over here, and I'm gonna add
a new team, and this can be The Sharks.
3:52
I don't think I have a Sharks team yet,
right?
3:58
I do, Polar Bears,
testuser is their coach,
4:01
and the practice location is
gonna be the Zoo Field, sure.
4:07
In case you didn't notice,
I'm making those things up as I go.
4:14
There we go.
4:19
So there's the Polar Bears.
4:20
So, the next thing I'm gonna
do is I'm going to make
4:22
a new incognito window,
which is gonna go to admin.
4:26
And I'm gonna log in with my testuser.
4:33
So they're logged in.
4:37
They don't have permission to edit
anything because they're just
4:39
an average everyday user.
4:42
So if I go to teams,
then here's all the teams.
4:45
We've got everything set up.
4:48
So I should not be able to go to
teams/delete/1 to delete the Tigers
4:49
because they are not the admin, or
the coach rather, of the Tigers.
4:55
So I got a 404.
5:01
The reason I get the 404 is
because when the view does
5:03
this queryset right here,
they're not a superuser.
5:08
So we get back only the teams
that they're the coach of,
5:14
which means we only get
back the Polar Bears.
5:17
And the Tigers, the PK one, which is for
5:22
the Tigers isn't in the queryset
which contains the Polar Bears.
5:25
There's nothing in there that has that PK,
so pretty awesome.
5:29
There are a lot of other methods that you
can override to get more customization.
5:34
Some are less common to use, of course,
5:39
while others are gonna
be used all the time.
5:42
Get_queryset is one of
the ones that's used a lot.
5:45
Another one that's pretty common
to override is called get_initial.
5:48
And this method allows you to give
initial or starter data to a form.
5:52
So I'm gonna use that
here in the CreateView
5:57
because I want to make it to where
the coach is automatically set,
6:00
it can be changed, but
automatically set to the current user.
6:04
So get_initial(self).
6:08
And let's say initial =
super().get_initial().
6:12
And the reason I'm doing that is
to get whatever the initial data
6:19
is if any has come through in
the stack of calls for the view.
6:23
As it is with this just
being a straight CreateView,
6:27
there shouldn't be any initial data,
but it's better to be safe than sorry.
6:31
So then, we'll set initial["coach"]
= self.request.user.pk because
6:36
coach contains a number, which is the ID
of the user, or the PK of the user.
6:42
So, in this case,
it's going to be self.request.user.pk, and
6:49
then I will return initial.
6:53
And this works pretty much just
like the get_context_data did,
6:55
with the idea of you're pulling in this
dictionary, you're changing a key and
6:59
then you're sending
the dictionary back out.
7:03
Okay, so now, let's go over
7:06
here to teams/create.
7:11
Then I see that testuser is
automatically loaded here for the coach.
7:16
And I can still select kennethlove, I
could select nothing and have it fail, but
7:20
it's pre-selected on the current user.
7:24
So pretty awesome.
7:28
As you can imagine, these few methods
are just the tip of the iceberg
7:31
when it comes to Django's
class-based views.
7:34
This is actually one of the major
valid complaints about CBVs.
7:36
They're full of methods and you have to
know exactly how the view is constructed
7:38
to know what methods are available.
7:42
Luckily, the Django documentation
is pretty solid here, and
7:44
there are great resources
out there like CCBV.
7:47
I've put a link to CCBV
in the teachers' notes.
7:50
So check it out the next time you decide
to go spelunking in CBV's inheritance
7:52
chain.
7:56
If you were here in the Treehouse office,
7:57
you'd see me using this
reference all the time.
7:59
You need to sign up for Treehouse in order to download course files.
Sign up