hey and welcome to the try django series
[Music]
my goal for this one is to help you
learn and master django like i want you
to go as far as you possibly want to go
and an understanding the django web
framework you see in the way we're gonna
do this in this one is really start from
the beginning we're gonna start with
absolute basics and then we're gonna
work our way up introducing new concepts
along the way and i'm actually not going
to be building a full project so instead
what i'm gonna do is just jump into
individual concepts put them into a
practical use case in a sort of project
and then eventually you'll have a very
good understanding of how to build real
web applications using django and of
course i do recommend that you learn
from entire projects and i have a bunch
of them both right here on youtube on
join CF EECOM slash youtube as well as
on our web site join CF e-comm we have a
ton of stuff there from building real
things with django but this series is
all about getting the absolute basics to
even advanced level things bit by bit
if you're learning Django for the first
time it's an incredibly exciting
experience at least it was for me
because once I was able to actually
build a web application with you know a
database attached to it it was like oh
this is so cool now I think that you
might be just as excited and perhaps
you've already done that with other web
applications or perhaps this is the
first time you're programming either way
the most frustrating part is at the
beginning not so much because of the
programming language but often because
of how to actually set up your system
and since it's so frustrating over years
we will find the way to set up your
system depending on what you're on and
that's part of the frustration it's like
you're gonna see me working a lot in a
Mac so Mac OS environment and if you're
on Windows you're like hey why isn't it
the same I mean actually using Python
and actually using Django is the same on
both systems because python is Python
and Django is Django the commands to get
there might differ slightly but
realistically it's the same now over
years we've refined the installation
process and all of that can be found on
join CFE comm slash from zero so if you
just do that step one that's setup
process you'll be ready for the rest of
the series you don't have to go on to
any other step other than setting up
your system before you jump there I did
want to mention one other thing and that
is the code so we have all of our code
on github or join CFE comm slash github
to shortcut it you're gonna look for the
try Django repository so so join C feed
comm slash github we'll take you here
and then if you go into repositories
you'll see all kinds of them and in fact
if you type out try Django you'll see
multiple there as well I want you to
ignore all of the ones that have numbers
in them and just go to the one try
Django right so this is a link right
here if you want to go directly there
but this code will 100% help you because
when you hit roblox what you're gonna
want to do is take the code that you've
been writing and take a look at github
make sure that what you've been writing
is the same as what we've been doing in
the videos that part is critical and
then the last thing is when in doubt
consult the documentation
Django's documentation is very
well-written and there's just so much
there that you can learn that we won't
necessarily cover because they give
additional context or they give
specifics to whatever use case you have
for the technology and then the last
thing is Google is your friend you know
you can use Google to do a search for
something that you're not familiar with
and oftentimes that will bring up Stack
Overflow dot-com Stack Overflow has all
of these questions from people for all
sorts of programming languages including
Python including Django including
JavaScript all sorts of things in there
and you just do a quick search you can
search for just Django and you can learn
a lot just from that just from going to
like with votes I mean does Django scale
that's an interesting question to take a
look at and then what is null what is
blank
I mean this right here is a great
learning resource as well so what I'm
gonna assume for the next video and all
the other future videos is that you have
your system set up and ready to work
with Django and Python the versions that
we're going to be using will be
discussed in the next one because they
will change over time at the end of the
day I really want you to stick with
whatever version is in the video because
as a beginner that is critical
all right so on this one we are going to
be creating a brand new virtual
environment and install jingo and if you
haven't done these things before
regardless of the version definitely
stop now and make sure you go back and
do the setup process now I absolutely
want you to have a fresh virtual
environment and a fresh Django install
not only just to get the practice of it
but also to make sure that we're all
starting from the exact same spot so if
you open up your terminal window or if
you're on windows your power shell or
command prompt but hopefully you're
using PowerShell fear on Windows Linux
and Mac users district terminal is fine
so if we type out python v and python 3
- V this is what I get now you might
already have Python 3 in there so if you
see Python 3 point six point five or
three point six point six right here
you're in good shape if you see this
then you're gonna have to do an extra
step okay
just keep that in mind I'm gonna leave
that open and I'm just gonna put it over
to the side a little bit and break it
down so we can just keep that in mind
while we're doing this okay so I've got
another terminal window open now you
absolutely don't have to do this but I'm
gonna leave it there just in case so
there's a few different ways on how we
can create a virtual environment and
install Django I'm gonna show you the
way that I'm gonna do it so I'm gonna
show you the final way and if that part
works for you great you can go to the
next portion which would be installing
Django which maybe we should just do all
of that at first so I'm gonna show you
exactly how I'm gonna do it now I first
of all want to keep this virtual
environment in one development area so
for me when I open it up and I list
everything out this is what I see yours
might be a little different
yours might be the same you might see
this dev folder if you don't see it just
do make their dev right so in my case
already have it there so I get this
error I'm gonna just CD in to my dad
folder alright this is where I keep all
of my development projects so here I'm
going to go ahead and make a directory
called try Django we're a CD into that
directory and then we're going to create
our
Virtual env now before it created I'm
just going to hit virtually NV and make
sure I don't see any errors I see that
there's all sorts of options I can do if
I type out ABC there is an error so if
you see an error that means you need to
install your virtual environment all
over again
okay so I cleared everything out but if
I do PWD I see exactly where I am I'm
inside of that folder if I list
everything out there's nothing in there
now all I'm gonna do is virtually and B
- P Python 3 enter now again remember
how I said if you had Python - V and
Python 3 was here you can just omit this
portion right here right
so if you see python 3.6 right there you
can omit that portion and just leave it
as virtually and be period we hit enter
that creates a virtual environment
inside of this directory so i can
activate it with source bin slash
activate and then install django so pip
installed django and my version of
django is going to be two point zero
point seven so django equals equals two
point zero point seven that should also
be your version of Jenko if you're
sticking with me on this use that
version of jingle I honestly don't care
if two point eight was two point zero
point eight is out use two point zero
point seven will upgrade things later
and if you stick with me on this you
will absolutely upgrade with us
I promise absolutely promise okay so I'm
gonna hit enter and I'm gonna let that
run now for those of you on Windows your
activate you might remember it's
different it's just slightly different
all that installs I'm gonna just go
ahead and break it down a little bit I'm
gonna open up another terminal window
and simulate reactivating this virtual
environment so I'm gonna list everything
out a CD into dev and then I see the in
to try Django I'm back into that virtual
environment so I can do source Bane
slash activate in a Mac environment in a
Windows environment of course is scripts
us activate anything you can also run
deactivate okay so deactivate just ends
the virtual environment cool so what is
the purpose of having a virtual
environment if you do
I already know well it's as simple as
doing pip fries you see all this stuff
I see Django one point ten point four if
I activate it slash bending activate and
do pip fries all I see is Django 2.0
point seven and PYT Z so it keeps these
requirements separate and when it comes
to Python and its projects like Django
you want to absolutely make sure that
that is done okay so we have everything
installed if if this part was done
you're ready to go you can move on to
the next one
if you had some issues or you want to
see other ways of starting a virtual
environment stick with me so notice that
obviously we had all this stuff
installed all that's working so going
forward just just watch just for
illustration purposes you know I'm
assuming that up to this point if you
have it working then you're done if you
don't have it working watch this next
part
rewind and then install the things you
need to install because I'm gonna go
pretty fast but still explain what's
going on okay so I'm going to close out
all of my terminal windows and act like
I'm starting from zero okay so I jump in
to my terminal window I go into I'm
going to go ahead and make a new dev
folder called dev - I'm gonna CD into
dev - and list everything out nothing's
in there so I'm just I'm gonna show you
three different ways in creating a
virtual environment the first one is
just type out virtually and B and then
the name that you want to give it so Vee
and V that is a way to do it now this is
irregardless of the Python version it's
gonna go off of whatever the system's
default version is so I type that out in
my case it's version 2.7 but that is a
way to start a virtual environment now
if I want to start it based off of a
specific version of Python I would do
virtual env V and V - P Python 3 oh so
let's call this V E and B - this gives
me a version of Python and this Python 3
so that assumes that if I type out
Python 3 it actually gives me a Python 3
but if you type out Python 3 and that
doesn't work this won't work so what
happens then well I can just do which
Python 3 or in other words find the
location where Python 3 is installed
right so which Python 3 will not work if
Python 3 doesn't work right so every
once in a while you install Python in
your system and it's just installed
somewhere else and this command itself
doesn't work but wherever that is
actually installed on any system and you
do something like this you actually
paste in the path to that and hit enter
that should actually open up Python 3
for you so then that means that the
final way to actually start a virtual
environment is virtual env ve and B 3
dash P and then the path to that Python
3 I hit enter and then will actually
start that virtual environment as well
now one other thing I will mention is we
can just make the directory that we want
to call it so and I want to make a
virtual environment and a brand-new
directory this is it I go ahead and hit
enter
I CD into it and then I can do virtually
env and then period instead of the name
and then whatever version of Python I
may want right so the order of these
things doesn't matter that much how I'm
running those commands in comparison to
what I was doing before but that's a few
different ways on how you can create a
virtual environment now in my case I'm
actually gonna go ahead and get rid of
that dev 2 folder I really don't need it
but it was all about illustration
purposes for getting all of this stuff
going ok so i'll CD back into my
original project and just go ahead and
leave it and that now if any of this was
confusing and you're lost re-watch the
video and do this multiple times because
having a basic understanding of starting
a new project installing it you're gonna
probably do this fairly often if you're
only here to learn some of the basics of
Django and you don't plan on making very
many projects which with Django you
maybe won't need to do it this way now
one more note I will say is perhaps
you're like hey I don't care about a
virtual environment I don't care about
doing all these things
well do that at your own risk right so
you're gonna run into issues if you
don't use a virtual environment and yes
I am not using Conda anaconda is a
package that's more for like data
science related things Jango can use a
lot of those same packages in my
experience anaconda and Jango don't work
that well but realistically if you're
using anaconda you're probably already
familiar with that system and you're
probably not gonna use virtual
environments
however I will save for this entire
series I would recommend they use a
virtual environment just to get used to
it just to get used to how web
developers often use the development
environment for Jango
now it's time to create a Django project
see I've got my brand new clean terminal
window open because I want to get in the
habit of knowing how to reactivate a
virtual environment so I come in here
and I CD into my dev folder where I'm
holding everything I CD into my try
Django folder where my virtual
environment root is and I just run well
no I don't run that virtually and via
command anymore
we go ahead and run source bin slash
activate right so that's Linux and Mac
users for you Windows users it's just
scripts slash activate okay so if you
are in here you can go ahead and do pip
freeze and you'll likely see this
version of Django that's the version
we're using that's the version I
recommend that you use as well so I'm
gonna just leave that open right over
here so we can always see it right it's
just a nice little reminder hey that's
the version of Django I'm gonna be using
all right now let's go ahead and do that
all over again it's really easy right
this this hopefully this is really
really easy if it's not really easy and
I'm going to fast maybe just put it on a
slower speed I know I talked really fast
but I try to get it so beginners can
keep up but also so advanced users like
more advanced web developers that are
just learning Django so all of you can
get something out of this that's really
the goal it's it's it's a little bit of
ambitious to achieve but anyways okay so
now we're in this virtual environment
and I have this command Django - admin
so Django - admin is a command that will
allow us to do all sorts of things with
Django but the main one is creating our
Django project so Django - and Men
creates projects and whatever our
project name is going to be now you
could do this right off the bat inside
of that virtual environment but what I
like to do is create an SRC folder as in
the source folder of the project and
then I go in there alright so if I go
back into my virtual environment I see
that it we have these things in here
right so I've got the for prop the for
things related to the virtual
environment and
I have my SRC folder so I change into
that SRC folder and just do Django - and
men start project and then my project
name what am I going to call it well to
be original I'm gonna call it try Django
that's the name of my virtual
environment as well I realize that but
that's okay you can name your virtual
environment and your Django project the
same because the virtual environment is
only for your system the project
yourself will be other places right so
like you'll be on github and there won't
be anything related to our virtual
environment so I'm gonna start this
project try Django and I'll just put a
period at the end because I am in that
SRC folder I hit enter and it'll list
things out I see managed to pie and my
try Django configuration folder that has
the name of you know try Django because
that's the name of the Django
configuration and if I run Python
managed to I start or excuse me run
server what I should see is it's saying
something like this
yes it's giving me some warnings we
don't have to worry about that yet but
it is giving me a web address that I can
go to so if I open up my web browser and
go there hey congratulations you have
Django working now if you're not
familiar with Django 2.0 and this is new
to you this is a new landing page that
they've created it looks a lot cleaner I
like it much better than the old one for
sure
so we now have Django working it's ready
to go so there's all sorts of things
that we can do with it but before I
actually jump in to Django itself what I
want to do is start working with some
sort of text editor somewhere that I can
write the code that is not necessarily
inside of the terminal because that gets
super tedious for especially for
beginners it gets very very tedious to
write code inside of the terminal so
we're going to do something different
and the next one we'll talk about that
so stay with us
in this one we're going to download a
code text editor so writing our code is
just a lot more user-friendly than just
typing all of the commands into the
terminal or PowerShell right so we're
gonna be using sublime text but another
one a another popular one is called
PyCharm or py charm I'm so sublime text
is 100% free to download and use if you
really like it you can just go ahead and
buy it I am not affiliated to either one
of these I just know that they're both
very popular choices to write out your
code and is if that's all you're really
doing here is you're just writing out
your code in these things they do have
some features to make them even more
user friendly but I'm not really gonna
go into that right now all I'm gonna say
is just go ahead and download this and
get it up and running and once you do
just open it up and you'll see something
like this right so you can have your
window open make make your sidebar open
and you'll see some blank page just like
this so all we really need to do is add
our project into it so to do that you
just go into project add folder to
project and then we want to navigate to
wherever our project is now in my case I
go to the hard drive users my user the
dev folder because that's where the
terminal opens by default is right in
here and then try Django I'm gonna go
ahead and hit open this brings in all
sorts of things in here right it brings
in virtual environment related stuff and
it also brings in my SRC folder which
has my manage two pi and all sorts of
Django related things right so so this
is one of those advantages of using a
text editor is it just makes it really
clean and easy to see what's going on
with any given code and it also gives
you these numbers or these lines of code
right so I can say hey look at line ten
and you're already can go boom
line ten okay cool so that's another
aspect of using a code editor that I
mean there's so many things to it that
I'm just not gonna go into now because I
could I could spend probably an hour
just going over the setup process of
sublime text maybe not that long but
anyway so we now have this folder in
here
and we're pretty much ready to use this
project but what I want to do is just
save the project inside of sublime text
in here and just save it as try Django
this workspace thing that's an extra
piece on our testing so don't worry
about that I save it in here I've got my
sublime project and of course if you
close down sublime text and you are in
your project itself and you have
something like this like your hey I'm
navigating through back to where it was
you know you can just double click on
this and hopefully it'll open up sublime
if it doesn't then just you know do the
thing that you need to do which is get
info and just say make sure that you
have open with you know sublime text on
there if you're on Windows its
right-click and you know doing the same
sort of thing where you just want to
make sure that it opens up but the nice
thing is then it just cuts to right
where all of my code is and I can open
up all the different files that I need
and make edits and changes to them
sublime text is really cool really like
them I wish they would sponsor these
videos they don't but I really like
their product so go check it out and
download it because we're gonna be using
it a lot it's not required but it is
highly recommended see you in the next
one
let's talk about settings hi this is
absolutely a basic thing that you'll end
up using a lot it has a lot of
implications for your project altogether
so we'll just go sort of line by line as
to what's going on here of course you
can read more on the docs because there
is more that is going on behind the
scenes than just what we'll mention
first and foremost we of course import
the OS because Jango works on any given
operating system Windows Mac and Linux
all of you guys see the exact same thing
if you've done what we've done to this
point so you see we import OS and then
we have this variable name base dur
that's set to this long string of what
the heck is going on all this does is
gives us the path of where managed up
high is but more specifically the folder
that is holding managed up high which in
our case is SRC so it's that folder
right there okay so how I know this is
well I know Python well I know Django
well but how you can figure out where
that directory is that's this right here
so baster just gives you in my case that
right so your user might be different
and if you're on Windows it's gonna be
different for sure that the slashes will
be in a different direction so the nice
thing here is we know that Django knows
where it is in the system that's that's
important right so we can do things
relative to Django inside the entire
project that's pretty cool and this
baster shows us that right off the
beginning and you know you could print
out what the baster is too if you were
so inclined you can print that out and
just run the server again let's go ahead
and run that server again and what do
you know it actually prints out that
directory for us all right just like I
said that's where it is that's what it
is cool next thing is the secret key
every Django project has a secret key
that's associated to it they're always
unique to that project or at least they
should be unique to that project and you
don't want to make it you know public
in production because it it could
possibly lead to security leaks and you
don't want that so just doing a couple
changes is good okay next thing is debug
this is something that's very useful
while you're learning or while you're
developing both things when you bring it
into a live server a live production
environment it's a real website with
real people real strangers using it you
gonna turn that to false and that has
some implications later allowed hosts
like domain names that are loud I'm not
going to get into that right now
installed apps this is a cornerstone of
Django install amps there's a bunch of
them installed by default which we'll go
over later but this is where you're
gonna build your apps like you know if
you have a blog that you're creating you
would put it in an installed apps if you
have products a list of products that
you have you would put installed apps
that is I mean very core to Django and
think of apps more in terms of
components then apps right so like apps
has taken on a new meaning like your
mobile phone has a bunch of apps it's
not like that it's more of like little
pieces of the greater Django project
itself middleware this is I mean there's
a lot of things going on here but it has
to do with your requests and how
requests are handled and also how
security is handled and stuff like that
this is something we'll go over later
it's definitely more of an advanced
topic but it's nice because it allows us
to know that there's a lot of security
features built in as we can see with
some of the ones that are already there
root URL Kampf this is something we'll
definitely cover for sure - this is how
Django knows how to route any given URL
you know so like I'm my server is
running right now so if I take a look at
that running server if I go to a slash
you know it whatever
this is URLs like so those things are
automatically routed by default by
Django something that's really cool as a
built-in feature in there the next thing
is templates you know like Django
renders out HTML templates
we're gonna go over this a lot but
basically like where do we store them
and how are they rendered how do they
work all that stuff we'll go over later
but it's essentially the HTML page that
gets rendered in Django it's really cool
it's very useful and it's definitely a
common topic that we'll go over the next
thing is the wsgi application this is
how your server works so the server goes
through and uses this setting that's
here in some cases you change it in
other cases you just leave it as is
next thing database is Django maps to
databases really really well
so MySQL PostgreSQL and a few others as
well very easily maps to it you just
change your backend here where it's
located and some of the other settings
you can go on the docs to see all of
that but by default it has a sequel i3
database already there as you might see
right there that's pretty cool next
thing is we have password validators
this just validates that passwords are
good or at least good to the current
standards of what Django is found we
have some internationalization stuff I'm
going to skip that for now and then
finally static files like where do you
store your images your JavaScript and
your CSS like where do you store those
things static files of something we'll
absolutely talk about as well but but
settings is kind of controlling all this
right so it's it's pretty fundamental to
how all of our Django project is running
and that's in our main configuration I
mean that's it that's it for settings I
mean we will talk and use these things a
lot more but what I did want to mention
is one last thing one actual practical
thing is is that that database thing so
we have this error here and to run our
database we can run Python managed on py
migrated so what this does is it
actually sinks our settings whatever
settings we have with our Django project
and in whatever apps we have we're gonna
go over this again for sure but all this
is is this right here so we've got DB
you'll I 3 I just said hey database make
sure you and Django are cooked up and
you're ready to start work
so if I actually changed this the db2 I
could run migrate again and what do you
know Django actually creates a brand new
database for me now this is pretty much
only true with sequel Lite if you had
MySQL or PostgreSQL you would have to
create those databases themselves but
for us we can just do whatever I'd like
as far as the database is concerned I'm
gonna go with the default of DB dusty
light 3 I'm gonna go ahead and delete
that file now we have a better
understanding of how settings work let's
go ahead and create our first app see in
the next one
now it's time to talk about one of the
key components of Django and that is
apps you should think of apps as
components or pieces of the bigger
Django project all right so they're the
little bits and pieces that can hold a
good amount of code but they're not like
apps like on your mobile phone right so
if you jump in to the code itself we see
that we already have some apps installed
by default right so this is also where
you'd put third-party apps as well as
your own right it's pretty cool so let's
take a look at the default or built-in
ones that we can look at the very first
one is called admin and if I go into my
project and type out admin I'll see
something like this this Django
administration all right so I already
have a user name and password filled in
because I use Django all the time but
you probably won't see anything in here
yet you know and actually the question
should be is like how do I actually get
in here well I'm gonna go ahead and jump
into my terminal notice that I have two
terminals windows open I have one that's
running the server and then one that's
just in the root of the jingle project
also known as fort manage top pi is you
can see how I got there right there so
there's a couple things that definitely
need to happen first of all I want to
make sure that I when I run Python
manage top py migrate I see something
like this right I have a few apps on
there that are built in those are there
by default I don't want to see errors
here essentially but you definitely
wanna make sure that my grid is done
because we want to create our first user
and that is Python managed to I create
super user that one command will allow
us to create a user that has access to
the admin this is not a regular user
this is just the ultimate super user
right so the user that you'll end up
using in my case I'm going to use the
user name of CFE I'm going to leave a
the email address empty and then I'm
going to type my password now the
password typing doesn't actually show up
and also when you're developing when
you're
testing in your learning you can use
whatever passer do you want here it
doesn't have to be that secure it has to
be secure when you go live when you
build a real project that's when you
really want to be secure so I've got my
username here and my password in my case
is just alarm code all lowercase and I
can actually log in to this admin ok so
what I did here was I actually create a
user that's actually in the database
Jenko did all that stuff for me I didn't
have to do anything really cool so that
makes things super easy super user
friendly and that same action would
happen regardless of the database pretty
cool so we actually just talked about
the first portion or first two portions
of built-in components or built in
installed apps right that's off an admin
off is that user right so I actually
created that user I created a super user
and then admin is what I just logged
into right so I can click on users and I
can see more about this off user I can
come in here and say Justin Mitchell
right and hello at team CFE comm and
what do you know that is my user now I
can save it I can do all sorts of things
in here inside of the admin we'll talk
more about the admin in the future but
it's really cool I can also delete users
I can go back and create new ones you
know there's a lot of built-in things
about the admin that are really nice but
this is all about the apps right the
next few things well they're not
relevant to us just yet
so what we want to talk about is
actually creating our own custom apps so
we've done some of the basics now let's
do a custom app of our own and have it
inside of the admin when I say custom
app I mean our own data so our own
structure of data let's see what that
looks like
in the next one
and that last one we saw some of the
built-in features of Django's project
right we saw some of these components
also known as apps that allowed us to
have a user and an admin those two
things are phenomenal they're really
easy to use and very user friendly but
what we want to do and the purpose of
using Django is to build our own apps
our own components now let's not confuse
apps with like what's on your mobile
phone it's much more about just little
pieces of this greater whole
that is your web application so let's go
ahead and jump in to the root of your
general project I'm gonna use that term
a lot the roots of the Django project is
referring to managed up high so we're
managed up high is assuming that you
have your virtual environment activated
and that's where you want to be whenever
I say roots of the Django project I'm
gonna assume that that's the case so I'm
navigated there and of course this is
where it's actually located on my system
it might be a little different for you
if you don't know how to get there just
go back a few videos in this series it's
linked below make sure that you watch
some of the basic stuff there anyway so
let's go ahead and create our own custom
app so I'm gonna go python man jump you
I start app and then whatever one want
to name the app now I'm gonna go ahead
and name it products and you can do the
same thing by pressing up and renaming
it to blog or you could do it to
profiles or you could do it to Cart
right so I can name it all sorts of
things right and honestly those four
names actually fit with like an
e-commerce project right and if we look
back into the code itself you see that
hey I've now have all of this new code
inside of the name of those different
apps that I just created
now this does show us something that we
could work towards like we could totally
build an entire project that does all of
these things but also what it should
illustrate to you is that each one of
these apps should do one thing and one
thing really well like the products app
should really just do product related
things not
heart-related things that should be
separate that should be in its own cart
app uh and we'll get to what that means
later but the idea here is that your app
should be pretty narrow in focus
once it starts to get wide that's when
you start to bring it into another app
and as you see it's really really easy
to create an app so there's really no
reason to not do it other than perhaps
laziness and I want to avoid that in the
long run for you that's why I'm telling
you about it now okay so I want to show
you how to use an app in the way of
storing data okay the apps are really
good for storing data and mapping what
data you want to store to your database
so that means I'm going to go ahead and
delete some of these other apps that I
just created because we just simply
don't need them because we're still
learning right
so I delete it deleted these other ones
and now I only have products so opening
up model stop pie we'll talk about the
other files later but for now just
models da pie I want to store a product
right so I want my back-end to have
memory of a product that I created how
do I do that
well I write a class called product and
in this class I wanted to have various
attributes to it right so I want to say
that it has a title I want to say that
it has a description and you know
perhaps that's it for now maybe I just
want title description maybe I want
price too okay so let's say title
description and price now I want these
mapped to the database so how do I
actually do that well in Django it's
actually fairly straightforward and we
use something called model fields so
models dot we just type out models dot
it's already imported by default and I'm
gonna just use a text field for each one
of these for now we'll talk about more
advanced fields later but let's just use
text field on each one okay and then my
product itself the actual class that I'm
using here I needed to inherit from the
default Django class of MA
okay so this means that it's gonna get a
lot of features that we absolutely need
to make this work that we just won't go
into just yet that's getting more
advanced but here is a very very simple
model called product this will map to
the database and we'll see that in just
a moment so since I created model spy
and I created this app I need to add the
app in the settings installed apps and
that's really simple I just put my own
here and just write out products the
name of the app that I created right so
that's the folder here so I've got
products I have installed apps I'm just
gonna go ahead and put a comma after it
and now what do I do
I of course make sure that I save my
settings top pie and models dumb pie and
now what I can run is this thing called
make migration so Python managed to py
make migrations and then Python manage
top py migrate okay so those commands
you're definitely gonna want to remember
so Python managed up py make migrations
and then Python managed up UI migrate
okay so the first time I did it it made
some changes the second time I did it it
did do anything right so I want to run
these in conjunction with each other
every single time I changed models top
pie so let's go ahead and add in another
field here and I'm just gonna say active
ok or let's just do summary instead of
description right so we got description
in summary those two might go
hand-in-hand but now I've made a change
to the model I saved it and now I want
to run make migrations again it's gonna
ask me for basically a default and I'm
just gonna go ahead and say 2 for now
we'll get into that later but I'm gonna
go ahead and say default and say this is
cool exclamation mark ok so I run make
migrations again and then I were on
migrate again now why the heck did I
show you all that well the main reason
is to remember that we always want run
make migrations and migrate when we make
changes to models up high anytime
anyplace anywhere that is super suit
important cool so we've got this model
now and I want to take a look at this
model inside of the admin so all I do
here is go into M and up high and do
from dot models import product so this
is a what's called a relative import
it's importing the product class from
the models PI and it's relative because
admin PI and models dot pi are on the
same you know directory they're in the
same module so I can actually do that
relative import and all I do here is
admin dot site to register and product
we save that and with our server still
running I go back into my project Maya
Django admin I now see this new thing
here called products and I can add a new
product new description some price and
the summary hey I've got my default in
there it's saying this is cool this is
awesome hey explanation mark hit save
and there we go we've now created a new
product and it's saved in the database
and that's the that's really the core
and the basics of it all right there a
basic model saved in the database now I
could use this over and over again to
save all kinds of data in the database
this is not a great model I will say
that like this is pretty limited in
scope on how it is we'll get into more
advanced features of that later but for
now that's pretty cool that's all we
have to do for a model that's it so what
we still need to do is see how to do
this in the Python shell that is
actually just using Python commands to
save some stuff
now what we want to do is just use the
Python shell to create new products so I
use the admin before now we want to use
the Python shell so to do this I want to
make sure that I'm in the root of my
Django project
you know we're managed up pi is and I'm
gonna run Python managed up whole py
shell so when you do manage up UI shell
that means that all of the Django
projects stuff will work inside of a
Python interpreter so I hit enter it
looks like a normal Python interpreter
but it's not because I can do from
products the models import product
alright so I can do these kinds of
imports I can import classes just like
we sort of did in the anime right I did
a relative important the admin this is
closer to an absolute import inside of
the show so I go ahead and hit enter
here and I can do product that objects
that all this is a built in Django
command we'll get over this sometime in
the future but for now if I editor I
seen that there's only one thing in here
right there's only one item and that's
because I only saved one in the video
that's all I did you might have done it
otherwise you might see a lot more there
and that's cool if you have that means
that you're experimenting that's awesome
but for me what I want to see is more I
want to actually create them right here
in the shell I want to have the ability
to do those commands so it's simple we
just do product up objects that create
and then we want to create new ones
inside of this command itself inside of
create itself again this is built into
Django this is default
by jingo standards right so in models we
look at the things that are required for
this product we have four fields that
are required so I can pass those four
fields in here as title new products to
write and description as another one
right price being you know whatever
price and then finally summary being
sweet okay
notice each one each argument in here is
a string itself right so I did that on
purpose there also
and that's how I can create a new
product a hit enter it creates it I can
press up and enter again it's creating
new and new products right and if I did
that product objects at all again what I
see here is a list also known as query
set again we'll get into that later but
it shows us all of those new products
created now assuming we still have our
server running which I do you can close
it out with ctrl C but if I just go
ahead and make sure that my servers
running I can come back into my admin
alright so you log into your I mean you
see this you go to products what do you
know I've got all those products in
there so that's another way to actually
create things in your database just by
using a command instead of you know
clicking through and going through the
form and doing all that pretty pretty
awesome
so we still have a lot more to do
obviously we want to see this in another
form but before I jump into another form
I want to see actually how do i
realistically create a model that isn't
so convoluted like i shouldn't actually
pass a string for price it should be in
the actual decimal right and perhaps the
title shouldn't be this long text area
maybe it should just be one short field
so there's definitely things that I need
to change to this product model to make
it better that's something we'll do in
the next one by adding new fields
so now what I'm going to do is actually
start over on these models I really
don't like what I did here so in order
for me to start over I can delete all
the files in the migrations folder and
just leave in it in there that's fine
also delete PI cache if you have it
there and then also I'm going to delete
my sequel I'd database okay so back into
my models I want to change these fields
to something different what I just did
was something you'll do often while
you're learning right you'll delete
those migrations and then you'll delete
that database sure you might lose some
data but that's no big deal that's part
of the learning process and that's
actually really really important to do
so with these fields I want to
transition them into being something
more realistic to what they are so let's
go ahead and look at the reference in
the the Doc's themselves so jingle
project comm look for the model fields
field types you can just do a quick
Google search for this and you'll see
the reference for all the different
field types and what we actually used so
far was just one of them as you see I'm
scrolling there's a lot of them so I
used just this text field that's one of
the very many that we have in here so
let's go ahead and use a few different
ones first of all the title field should
be limited to how long it is so I'm
gonna change it to a char field and I'll
add in something called max length and
I'll make it at most 120 characters
that's still a fairly long title but
that's what I want it to be and when you
use a char field you have to use max
length so max length equals to required
well I'm gonna leave it out for just a
moment and save it and now I'm gonna go
ahead and try and run my migrations
right so I'll go Python managed um py
make migrations I get an error says char
fields must define a max length
attribute I just mentioned that was
required but luckily Django will tell us
if something is required once I save
that some of my arrows go away right
description text field that actually
makes sense but what if our products we
don't necessarily
want to have a description then I can
say blank equals to true and I can also
say no illegals are true
I'll explain these the differences
between those two in just a moment
price what should our price field be
well should be a text field or should it
be well let's see if there's a decimal
field hey what do you know there's a
decimal field and a float field I'm
gonna stick with decimal field and this
is where the docs come in and make
things a lot easier for us this will
show us what's required okay so what's
in here is required so these two things
are required right here whereas if we go
down a little bit it says duration field
we're not gonna use that but there's
nothing in there that's required
we've got email field that has a
requirement but it's already in there
it's already built in so this will take
some time getting used to but that's
essentially what's going on with the
docs
right but it also shows you inside of
the docs that it has those required
arguments in other words let's go back
in here and change this just a decimal
field let's save it I save it it's gonna
run these errors right it shows me these
errors it tells me exactly what it is
but so does the docs right so the doc
says max digits and decimal places so
let's go ahead and add those for a
product decimal place is going to be two
like you know it's not gonna be three
decimal places you don't have three
decimal places of cents and then max
digits as in the number of digits this
will allow like a thousand digits is
actually a lot for a decimal number
right so just do that in your mat and
your head what's ten thousand digits in
dollars that's a lot right cool so I now
have a little bit more robust fields
summary I can leave it as a text field
as well maybe I want summary to be in
there by default maybe I want it for two
for sure be in there but I'm gonna go
ahead and get rid of that default I'll
explain the default thing in just a
moment most likely in the next video but
I will explain what's going on with that
here shortly okay so I save this and now
what I need to do is actually run my
migrations again remember
every time you change model stop high if
the Ron Python man stop you I make
migrations and then Python managed to py
migrate now I deleted the database so
that also means that I need to run
create super user all over again and I'm
gonna leave it in SC Fe type in that
password of learn code and there we go
my server is still running through all
of that my server still running i
refresh in here on the Django admin I
still have to go back in log in and I
see that I actually don't have any
products anymore but if I go to add a
product the layout of it has already
changed the title can't be some long
title I can say new product and
description I can write stuff if I
wanted to price has now a number item in
here so I can actually write numbers
$29.99 and I can add a summary some new
summary exclamation mark I hit save what
do you know not a whole lot different
okay with that in mind let's just see it
in the shell too so python managed to py
shell and we'll just go ahead and do
from products top models import product
this is the exact same thing it's just
going to the location still where that
product is we hit enter product objects
that create title equals to newer title
price now we can put actual a decimal
number in here no string so to 39.99 and
then summary now string awesome sauce is
awesome we hit enter it looks like it
created it no problems we go back into
our products in the admin still running
we see that we have a new product in
here all of that stuff was saved so it's
bringing those two things into
conjunction with each other so we're
already starting to save stuff we
already hopefully see how easy it is to
map data in Django
and this one I'm gonna make a new change
to our model without deleting the
database so or the migrations for that
matter so that means that we want to
actually know a little bit more about
what's going on with both of those
things so when we run make migrations
and migrate it syncs the database with
our model but if we add a field to our
model the database doesn't know about
that field so we have to make sure it
knows and make migrations and migrate
often allows that to happen but it also
introduces a whole set of like question
marks like the field that is being added
into the database what about all of the
previous things word that were in that
database so let's let's see what I mean
right so if I jump into the admin I see
that I have these four fields here right
but if in my models I decided to say
featured field right and I wanted to use
let's say models dot boolean field okay
so I I'm now trying to add this boolean
field but this particular object this
saved object has no idea about this
field right all future ones might but
this particular one doesn't so if I went
ahead and saved this and went to Python
managed to py make migrations right so
you do that by default you get this
error it says a non knowable field I did
mention that I would say what these
things meant that's what this is right
so if I said null equals to true here
this error would not have happened
because it would have said all of those
old values just leave them empty in the
database they can be empty that's fine
no worries but I don't want to do that
instead what I want to do is I actually
want a value for those old items in the
database it could be one item it could
be ten thousand jingle actually doesn't
know how many items that are in the
database that haven't been sent yet
again it could be zero items now that
what Django is going off of is this
migrations folder here it's going off of
this initial value notice this initial
one right here it's
checking against what's in here for this
model it's saying hey the new field that
you're adding this new field right here
isn't in this initial description it's
being added to it so we're gonna assume
that the database needs to know about
what's happening there so we need to
tell the database what default things we
should do now you can do that
there's several actions you can do here
right in the code you could say no legal
is the true or you could set a default
or you could do both right so you can
have a default in there right
so null equals a true or default value
in this case this is a boolean field
which means either true or false
you could say default equals to true so
you could absolutely hard right right
those and the code or you get this error
and you can provide a one-off default
for all of the previous things that were
in there and I'm gonna say one and
literally say true right so this means
that everything that's in the database
it's gonna go through all of them that's
already currently in the database and
it's gonna save those things as having a
field of featured with the value of true
as opposed to false
I had true there we go now that make
migrations what that ended up doing is
it developed a file for us a migrations
file and this is it right here the
database still doesn't actually know
about anything right it doesn't know
about this field steal still because we
didn't run migrate so I can actually
come back into my Django project and I
get this thank no such column he goes to
that right so that's an error that you
might see quite often I know you will
actually because people forget about
this so we want to run Python managed up
py migrate because we always want make
migrations and then migrate and then
there we go now we have a change
actually made and as we see all of our
old objects that are stored in the
database have featured as true all of
the new ones there is no default in
there cool so that's awesome what that
also means is then in my models this
summer
what if I wanted that to not be required
anymore well I can say blank equals to
true but let's go ahead and say null
equals to false and see what happens
here what did I do I make changes to the
models so what do I have to do I have to
run Python managed up you I make
migrations and then Python managed WI
migrate cool so now that I've got that I
come back in here i refresh summary is
no longer bold and I can now leave it
empty in the database so if I change
blank equals to false save it again run
make migrations and again migrate I can
go back in here and refresh and notice
now it says that it's bold so if I had
save and continue' it'll give me this
field is required so all this is doing
is blank has to do with how the field is
rendered null has to do with the
database so if the blank is false
meaning that it's required then it will
render as required that has nothing to
do with the database as we see with
these two things here but null being
true or false means that the database
can be null or empty in the database
cool so that is changing some items in
the model this used to be very very hard
and even if you feel like it's a little
challenging doing this several times
breaking it the leading the migrations
fault the migrations in here already to
lead in the database running all of that
stuff all over again doing that several
times will really get you comfortable
with models I promise you it will and
then try to explain it to somebody try
to explain it to a friend make a video
try to explain all the things that I
just did go back and reference them read
the docs whatever you need to do to
really better understand how this basic
stuff of models works so there's
definitely more stuff we can do in
models but I'm going to kind of leave it
as is there's other things that Django
does really well that we want to start
talking about and that has to do with
views and URLs
so we want to change this default
homepage to our own custom homepage how
do we go about doing that well we do
this by creating a class or a function
based view so a view means that it's
gonna handle our requests I'll get into
all of that later but right now what we
want to do is just illustrate the
purpose that we're doing so I created a
new app called pages I added that pages
to settings installed apps all right you
want to get in the habit of doing that
whenever you create new apps but you
should know how to do that by now that's
why I didn't do it okay so inside of
used up hi we see that there's nothing
in here this is where you're gonna be
creating all sorts of things for your
pages think of views as a place that
handled your various web pages just
think of it that way and we're gonna do
this using either functions or classes
written in Python so the first one I'm
going to do is just a home page and
basically it's just a very simple
function it's a home you give it a name
whatever name you want I would probably
say that mostly you'll probably add view
to it like you're not gonna call it home
page with that view
right so I'll get into view and all that
stuff later but let's just call it home
view okay and then it's going to return
something we wanted to return some HTML
so let's say for instance I wanted to
say h1 hello world now if you're
familiar with Python you'll know that
this is just a very simple Python
function it's actually nothing in here
is related to Django so we need to
change it to be related to Django now
this string right here has HTML in it
this is a string of HTML code it's not
actual HTML code we'll talk about that
later but this is definitely useful if
we want to just have one string of HTML
code for some reason but how do I
actually make this functional to do that
we use from Django HTTP
import HTTP response an HTTP response we
can just call with that string of HTML
code it's just like that we're really
close to making this an actual
functional view or a functional page so
I'm gonna go ahead and add args and
keyword args in here if you're not
familiar with args and key word args I
definitely recommend that you look that
up on Python this is Python specific if
you're not don't worry about it it's
okay you can look it up but for now we
can just play around this okay so I've
now created a function all this function
does is return back some HTML code that
says hello world but it returns it back
in something called an HTTP response
okay so let's actually make this work
I'm gonna save it and I'm gonna hope for
the best refresh here it doesn't work
well what if I try a different page like
ABC that also doesn't work but it says
page not found and it says something
about URLs well this is where we
actually wrap in our URLs this is where
URLs comes in and when we went over the
settings we did mention about the URLs
right here so URLs are in Tri Jango URLs
or otherwise the settings module or the
settings folder inside of URLs this
configuration folder has settings and
URLs in there and it has one that we've
already been using which is admin but
that's the only path it actually has so
now what I want to do is actually import
that view to work with my URLs now you
already have some of this stuff in here
right so this is actually written for us
so I can go off of what they have
written in a similar fashion by saying
from pages right so pages would take
place of my app import views and then I
can quite literally add this URL pattern
like it says in the code or in the
comments there and I didn't call it home
but instead I called it home view right
so there
I'm just going off of what they've given
me home view and home view we save that
and let's go back to our home page hello
world cool it's actually working there's
a couple things that I don't
particularly think is a good idea with
how this is written is that what if I
wanted to use the product views then and
I went from products import views things
get confusing so don't do it this way
go views import home view import the
actual view that you want to use and
then just put that down there okay so we
say that and when you know the same
exact response Wow that's fairly easy to
work with not a whole lot going on here
let's talk about URL patterns and how
this portion works in conjunction with
our view now URL patterns you notice
that I had this empty string that's in
this path so if I actually copy this and
paste it down here and say home and put
a slash at the very end of it and save
it I can actually go into home and that
same thing will come out where if I use
a different page like ABC that won't
show up and the page not found is
because we haven't routed a path to that
view right so let's say for instance I
want to call this contact and you know
we can we can actually ignore this name
stuff for now but if I want to call this
contact sure it could actually go to
that same home page view but really you
would probably want to have another one
called contact view and again we'll do
ours and keyword args and then we'll
return HTTP response and then we'll just
say h1 and contact page and close out
that h1 tag and then we would import
that as well just like that
and there we go so that would give us
that contact page pretty useful now
what's actually happening inside of this
path right so the URL when you go to a
Django page right so we we go to a
Django page right here and Django knows
that something is being requested that's
different so the first thing that's
being requested is just this home page
and then if I go to another page like
contact that's a new request and it's
getting that item whatever is in there
and Django is smart enough to know hey
that URL is being requested look in this
URL spy or that main configuration that
we have set up by default it's gonna
look for that URL and then with a
matching URL it's gonna look for a view
that is made to handle that URL
right so we already had those views that
were made to handle it you know we can
have as many views as we want it's
completely up to you and in fact your
project might have a lot of views right
so like social about whatever like all
of those things you can absolutely start
playing around with and I recommend that
you do I recommend that you take this
and play around in the sense that hey
how does this actually work and how can
I make all of my own pages now there is
a critical thing that is missing here
but I'm not gonna get into that just yet
what I will say is that remember when we
go to a URL we're requesting something
from that URL it's kind of like knocking
on the front door of somebody's address
I mean it's not a whole lot different
than that except this is digital we're
going there we're knocking we're asking
for something or we're requesting
something in this case we're requesting
a web page that's at that URL so what's
actually happening is on these views we
have args and Kure dogs to just capture
everything so if I actually print it out
let's go ahead and print out args and
keyword arts and go back to that home
page and look into our terminal we see
here are the things that are being
passed we have this WSGI request hmm I'm
requesting something so that means that
it actually is an argument that's coming
through here I can say request and then
args keyword arts right so each one has
requests coming in here by default so if
I go back refresh now my args and Q were
dogs are empty and my request is
absolutely in there so I can print out
that request and we can see it so what
does this request do exactly well
there's a lot of different things that
it can do but one of them that's
important for us is request a user so
this is where that authentication stuff
comes in this is where logging in your
users come in but this is also how our
views can access that so if i refresh in
here I can see that hey my CFE user has
logged in
if I opened up an incognito window or
just another browser or logged out I
would see that it's an anonymous user
it's not somebody that's actually logged
in so so both things are actually valid
and they are really good to know because
then I can do all sorts of stuff with
this request user now that's a little
bit more advanced so before we get there
I want to make this basic web page or
this basic application work better for
us like so far we have this HTTP
response and it's rendering our HTML and
that's great and all but you know you
might be familiar with HTML hopefully
you have some background HTML just
having h1 being rendered that's not very
good like notice like my head is empty
it's just h1 that's the only thing
that's coming back so now is actually a
really good time to stock talk about the
Django templating engine so we can
override this a shibi responds with a
nother sort of thing called Django
templating
quick recap we go to a URL it's like
we're knocking on someone's door
requesting something the server or Gengo
returns a response to us that is the
process that always happens with
correctly configured Django projects now
when this happens
Django recognizes what URL is being
requested or you know that web address
is being requested it breaks it apart
figures out what function is going to
respond to it right and with that
function we want to respond with some
sort of HTTP response the the basic
default one is this just a sea of your
response and we can pass in whether it's
HTML itself or just a string it doesn't
matter we can return HTTP response and
we can even return it being nothing like
it could be absolutely empty in here and
it would still work so this is still a
valid page but what we want to do is
instead of writing in strings here we
want to use some built-in shortcuts that
Django has and you may have noticed that
shortcuts dot import render was in there
by default so when you create a new app
that's in there okay so I want to
actually be able to use this itself so
instead of returning HTTP response what
I want to do is return render and it's
going to take in a few arguments one is
request the request argument that's
being passed one is going to be a
template name let's say for instance
home HTML and the last one is context or
for now we'll just do an empty
dictionary we will talk about context
later so that's how you would be able to
return some sort of HTML template or
HTML document either way so how do we
actually by how do I actually find this
like where's that located if I save this
and refresh in here I get this error
template does not exist well it
certainly doesn't we haven't actually
created it right and it's looking for it
throughout our site but it doesn't
actually know where to go so we need to
create a location for
and that's what we'll do now inside of
our SRC folder in the root of the Django
project we're gonna make a new folder in
here called templates this folder is
gonna hold all of our templates as we
see fit so inside of there we're gonna
go ahead and do home dot HTML making
that new file notice templates is online
with pages products and the Django
configuration folder as well as manage
top pie so I'm gonna put a home dot HTML
in there and I'm just going to h1 hello
world closed off h1 and then do a P tag
this is a template close out that P tag
okay so we save that seems like things
are looking good
we made a template folder home dot
html's in there we want to render it out
save it let's go back rerun it hmm
template does not exist still well this
is because we haven't actually setup
Django to know where these templates are
I mean I did name it templates but
that's an arbitrary name that directory
is an arbitrary name it is a best
practice name but it is still I just
made it up okay so in settings not pi
then remember how I said we were going
to come back to templates if you watch
that video
that's this so we want to actually put
in side of our ders or our directories
where this directory location is now I
could hard code it to your path to
templates and let's do that so let's go
ahead and say PWD here is my normal
project here right so that's to the root
of the Django project all I need to do
is add templates here as in the name of
that folder I hit save and refresh in
here what do you know our templates are
looking good they're actually in there
but if I sent this to you on your
computer it's not going to work unless
your User is CFE so what we need to do
is pretty much copy what we did here
that's actually fairly straightforward
but with some minor exceptions basically
I want to make it OS independent I want
to make it allow it for me to send
code to you and it still work so it's B
OS path that join baster and then
templates so I'm just joining that base
directory where manage top is with the
templates directory that I just created
I'm refresh in there it's still working
at templates still showing up so what
this allows me to do then is to make
multiple pages like about HTML contact
HP ml and so on and then I can just
quite literally bring in all this code
here and say contact and about and then
in my view just like I did on home view
I could just read change these about and
contact to content to the correct name
so about an HTML and contact that HTML I
say that refresh everything is looking
okay to go to about hey looking cool so
it's rendering HTML notice that it
doesn't have a dot HTML here right so
it's not actually like rendering out
that raw HTML file it's it's actually
going through Django and Django is
rendering out that each tml that's
pretty cool so if you've worked in web
design before you'll know that that dot
HTML being gone makes these URLs so much
cleaner and it's a lot easier to
navigate and share and it also makes it
look more advanced in my opinion okay so
now we have a way to render out HTML
documents but you might see that there
is a lot of repetitiveness that could
happen in these documents so we need to
talk about some basic inheritance stuff
with Django templates that's something
we'll do in the next one
time to talk a little bit more about the
Django templating engine that we are
actually already using but we want to
learn more about it so if I look at
something like this we've got two curly
brackets request dot user two more curly
brackets this is something that Django
does by default and it actually will
render out that relative information so
we actually refresh in our home page and
I see that CFA user that's my user name
and if I open an incognito window I see
anonymous user that's expected so that's
part of what's built into the templating
engine we can we can use the user model
in it right and I can also say dot is
authenticated as in is logged in and
it'll say true or false depending on if
they're logged in right so there's
definitely a lot of things we can do
there which we'll talk about a lot more
soon so make sure you subscribe to get
everything
but what you also should notice is that
our views are rendering out three
different HTML pages that actually might
share attributes across each one let's
say like a navigation bar or more
importantly some metadata like you know
if we inspect the element here and we
saw like you know the title tag or the
description tag or other metadata that
we might need to him implement in here
or some CSS data I mean there's a lot of
things that each one of those pages
would actually be able to use
so this is where template inheritance
comes in and where it's really useful
for us so what I want to do is create a
root page the page that all these other
pages are gonna borrow from so go ahead
and call it based on HTML based on HTML
is convention that's how you're gonna
want to call it um so and you're gonna
want to make it a actual HTML document
so doctype HTML and then HTML closed-off
HTML and then body
and body okay and then we want to do a
head tag here and in this case just to
show that this is actually working and
we'll go ahead and put a title tag and
say codeine for entrepreneurs is doing
try Jango hey hey okay not really that
clever but it is something so we've got
our head tag our body tag we have some
HTML in here we've got some stuff and
now what what do I want to do well each
one of these pages I want to also have
all of this stuff the exact same stuff
how do I do that
well what I can do is come inside of
this based on HTML curly brackets %
block content % curly brackets % curly
brackets block or curly brackets % block
or rather in block okay so this syntax
might look a little weird to you but
basically it's saying like hey whatever
is in between here whatever comes in
here let's just replace it so replace me
okay
that's all I'm saying we're gonna use
these blocks these exact same blocks on
any given page so let's say for instance
this I'm gonna go ahead and cut this out
and say just like that so I've got a
block here and that's the content that's
gonna be it's essentially gonna be
copied here brought in right here and
all I have to do to make all that happen
is extends based on HTML again these
curly brackets percent signs it
definitely can get a little confusing so
make sure that you are testing this on
your own to make sure it's working okay
so I've got now a new thing for home dot
HTML back in a home look at my title tag
if i refresh and now change to coding
for entrepreneurs is doing try Django so
that title tag actually did change and
it's based off of this based on HTML so
let's do that again on about instead of
about curly brackets
and extends based on HTML okay so this
is now pulling from based on HTML if I
saved it just like that and went into
that about page
it just says replace me ah so so it's
rendering out this default page that's
all it's doing so in order for me to
actually replace whatever block is in
there I have to use it
I do block content curly brackets Oh
curly brackets % block that is the
Django related stuff content is a
variable that I created and then we do
in block to close it off you might also
see in block content that's okay too so
we say that and we refresh and that is
now changed the title has changed so we
now have template inheritance and then
of course the final thing would be true
with contact as well so again we do
extends based on HTML and then block
content and then finally in block just
like that so the content that I'm
actually using is right here but now
each one of those pages is uniform in
Django this makes a lot more sense when
I use something like a navbar so let's
just go ahead and I'm just going to use
h1 or an h1 tag just to show this is a
navbar not to get into too much of the
HTML here but this is a navbar it's on
my about page it's on my contact page
and it's on my home page all right so
it's definitely the same thing all
across and that's how this inheritance
actually works and I will say that you
know if you change this to block content
main or something like that and I save
that every single one of those pages
would change right because I'm not
actually rendering or I'm not replacing
the correct block and each one of those
pages instead I'm replacing nothing so
they just don't do anything which is
really cool that actually makes things a
lot easier for us in the long run but
this might be a little tricky to get
your head around on
this actually works so what I do also
recommend that you pause the video or
stop now and change it to another
content area and do several blocks in
there to see how all of that works to
make sure that they you have a better
understanding of how this inheritance is
because it definitely is a little bit
trickier than just rendering out an HTML
page just a blank HTML page but it is
important so we will still do more stuff
on Django templates but that's it for
now
so what inheritance allows us to do is
to remove redundant code that we need in
many places what we're going to talk
about in this one is the include
template tag so we can do this more of
the same just on a little bit more of a
different level so what I mean by
include is sometimes you'll have a nav
bar or a navigation bar that you might
want to have in multiple places so to
allow this to be showing up in multiple
places or allowing me to edit just that
navbar not having to go into the base
every time I can actually come in to my
templates and let's just make them for a
new one called the nav bar dot HTML and
this itself will just be the nav bar
it's not gonna anything else it's not
really gonna be doing template
inheritance instead what we're gonna do
is have a nav bar of some kind right so
I just wrote a nav and then did a ul and
here and you know did some nav bar
related things I'm not gonna make a real
nav bar really but let's go ahead and
just say brand there we go so we've got
a simple nav bar with just brand and
let's say contact and about okay so we
save that and go back into base HTML
let's get rid of this this is a nav bar
thing alright so we just want to go
ahead and use include so again curly
brackets % include and then the path or
where that that actual HTML document
lives and we'll say simply just nav bar
dot HTML you know so this is very very
similar not very similar it is identical
to our views that we created right so
whatever we put here would be very the
very thing we put here so that same path
we'll get into that more later but this
is how we can include an external
template into any of our templates so we
save that and refresh and there we go so
we now have a nav bar granted it's not a
very good one but it is a nav bar that
will show up on all of our pages cool so
this the reason you do this is once your
project gets complicated once
you have like a big old project you're
gonna want to use this include because
then if I need to make a slight change
to my navbar I can just jump in to
navbar HTML pretty cool very useful so
now what we want to do is actually talk
about context so like how do I actually
use things beyond just that request user
that we've seen before so I want to
actually add in some new data that's
coming from other places so I'm not hard
coding it every time but rather it's
coming from somewhere else
so the main purpose to use templates and
Django is not so much for inheritance
and including and granted it does those
things well and you could make a pretty
cool website but what we really want is
data from the backend we want data from
the database that's being rendered out
inside of one of these templates we want
to see that we kind of teased it a
little bit with that request that user a
few videos ago but but I want to
actually go a little bit further and say
you know maybe I want to change the
title of a page or I want to have
different content in there based off of
a different user now we're gonna work
towards that but the initial thing that
we have to understand is what's called
template context and that's what we're
gonna cover in this one so let's go
ahead and jump into our views and I
leaved our left out this dictionary
right so it's an empty dictionary right
now and that's actually where we can
pass in context to our template because
what Django does is it takes our
template and the template context
matches those things together renders it
and then sins Bank just raw HTML to the
browser will see what that means in just
a second but that's essentially what's
happening
it takes the template they take some
context Masha's those things together
turns it into regular HTML and then the
user sees that okay so what do I mean by
context exactly what context could be
any data type right so let's go in our
let's say our about view right so let's
make a dictionary just a standard old
Python dictionary and say my underscore
context equals to a dictionary alright
so if I grab my context here and put it
in and replace that empty one we've got
the same stuff going on right now okay
so I said that I wanted to change my
title so let's go ahead and just have
some arbitrary key meaning I'm making up
this key and we'll say my text and we'll
say this is about me or us whatever okay
so this is now my context all of this
stuff is arbitrary I made it all up
as you probably could guess
but we've got a key/value pair here so
it's just a standard dictionary with a
key as a string that's a standard thing
in Python and then I can use a string as
the value or I could use something else
like a number or rather let's say
something more like my number and we
could do one two three right so I can
use strings I can use numbers I can use
other dictionaries which I'll let you
play around with the datatypes yourself
because that's not really what's
important what's important is how we
actually bring this into context into
this about page so since I've got this
context I have this dictionary in here
I've created a custom one for myself I
want to bring this into that template
and take a look at that template so I
have two different key items here so
let's go into about about dot HTML and
let's also make sure our project is open
on that page as well so we'll go to
about here and there we go so we're in
that project that's rendering out this
template and how I actually render out
any sort of item that I passed in as
context I would normally bring in my you
know something like a P tag so a general
HTML here and then whatever context I
want to use so we use these curly
brackets twice so curly bracket curly
bracket or braces space well put
something in the middle there and then
curly bracket curly bracket and then
we're done okay so what is it that I
need to go in the middle here so this is
called a context variable right so a
context variable meaning what variables
did we pass into our context and what
can we use we already seen request that
user so that is something that's already
built in there right but how do I
actually access the things that I pass
through well hopefully you have some
intuition about this if not it's okay
you'll develop it we have these two
variables so our keys become the
template variables that are inside of
any given context that we pass so now
what i've done as i said hey django
we've got this about dot HTML page and
then we have this context i want
to mash those things together and
produce something that I wouldn't expect
so in that context back in that HTML we
can say my underscore text and that
right there should render out this key
and that value right so it's taking this
key that's what we used and it's gonna
render out this value we can do that
same thing with my number so back into
about we can say my text underscore or
rather comma curly brackets curly
brackets or braces opening closed
sublime text does it for us but you know
if you're using a different text editor
you want to make sure that it's done
this way and they will say my number we
say that we go back into our bow page we
refresh it oh oh we're not actually
getting anything why is that
well it's actually possible that I
didn't save my about view context so I
need to make sure that I'm always saving
everything right so I mean if it's empty
that means it didn't pass through it
means that the context was empty it
means that this stuff wasn't actually
set it's a pretty cool error to see
right off the bat it's not really an
error it's actually a feature but if we
refresh in here now we see that data
coming through so that at its simplest
form is template context and it's again
just a really quick thing we make a
dictionary of the template context that
we want to pass and then we pass that
now one of the things that you might be
wondering is saying like my list and how
do I actually work through with a list
so if I said 1 2 3 you know in some
numbers or strings it actually doesn't
matter how do I actually look at this
list right so I come in here and I say
my list I render out that list well
that's nice and all but that's not how I
want to see it I want to see it in maybe
an actual HTML list item right perhaps
that would be a little bit better so
this gets a little bit more complex and
that gives us the discussion of what's
coming next
we lift it off where we passed in some
template context of a list and we want
to see that actually rendered out we
want to actually look at what that list
is in a different format right so the
format I want to see is something like
this so let's do a ul inside of our
template and do a list item so item 1
and then close off that list item list
item item 2
ok so how would we go about doing this
there's there's a couple ways that you
can do it but the main way let me say a
couple ways that you could do it one of
the wrong way let's do the wrong way
first the wrong way would be to come in
here into your view and render out the
list as different variables so in other
words saying like for item in some list
so let's just do another list here and
then doing my context and something like
this item a equals to item grunted this
is not the greatest because it's only
gonna end with that but essentially you
don't want to do this you don't want to
go this route but we are starting to
move towards what we want to do in the
template and that is we want to create a
for loop within the template so the
templates themselves can have this sort
of flow we can actually go into a
template and we can run a loop on any
given context object or constant context
variable so to do that we would just go
ahead and do curly brackets or braces %
4 and then some arbitrary you know
variable name I'll go ahead and say my
sub item in my list and then curly
brackets and with templates it is
different than Python it's closer to how
like HTML would work so if you open a
for loop you must close a for loop so
there we go we have a way to actually
loop through this stuff and then all I
have to do is put a ul on the outside of
it and then a Li
on the inside of it and then we could
just use those curly brackets again two
braces and do my sub-item and we save
that and what this will do is actually
iterate through every single item in my
list assuming that there's stuff in that
list so if i refresh in there now we see
those two new things right so we
actually see these things that are rated
out and they're shown up here and there
are other additional features to looping
in here one of them being like for loop
dot counter and this allows us to see
what iteration number we are currently
so if i refresh I see that it goes 1 2 3
right and granted in my view if I were
to change the order or change the values
and even have you know ABC strings like
that stuff like that all of that will
come through it's pretty nice I mean it
allows us to do all sorts of things
inside of our template that's based off
of what's coming through our view now
don't get me wrong
we still aren't seeing data from the
database like we're still hard coding
all this stuff like I do want to work
towards where I can actually see data
from the database but there's still a
few more things that I want to do with
templates and views before we get there
so now what we want to talk about are
conditions in a template that is an
if-else statement inside of our template
itself now by and large you want to make
sure that your logic is already handled
in your view that son of a general rule
of thumb I'll get into that a lot more
later when we get more advanced but
basically if you're going to be doing a
lot of if-else statements you're gonna
want to do those in the view and change
your context that you're rendering in
the template you don't want the template
to do too much that work but there are
cases where you will want your template
to do it and I'm going to show you a
very basic example of that but I'm also
giving a give you a little bit of a
warning with your variable naming with
templates okay so the first thing is
when you have your context here and you
render it out and let's say for instance
you do have a list like this we're gonna
want to be very selective about how we
rendered that inside of our for loop so
in other words if I changed let's say
for instance my text to being ABC and
then inside of my about I have ABC here
and then I change my variable in my for
loop as ABC the things get a little
hairy and they might render fine right
so it renders out fine but then when I
actually want to do a condition such as
if ABC equals to 3 1 2 you know if
that's the case then I might want to
rethink on how I actually named my
variables because they are I mean then
this is already looking tricky like I'm
already unsure of what's going on so
let's keep this in as my text and my
text something like that is frustrating
when it happens when you don't catch it
but it is something that you'll gain the
skill of over time I promise you it's
just about recognizing how you name
variables and this is true in Python in
general right so sometimes you might
name a variable one thing and then it's
rendering is something else it's also
true with functions and classes I mean
I've seen it happen a lot and it's
happened to me so much so I just wanted
to bring your attention to that because
of what we're doing right now
okay so going back into this about page
I have this condition here right so I
actually created one and it's really
simple we just call an if statement so
percent if some variable or some thing
that would be able to compare to another
thing or more simply if something is you
know true so you could also pass in a
context variable in here so back in my
view I could just say this is true and
just set it equal to true right so I can
I can still use that so these conditions
what they allow you to do is just
evaluate whether or not this statement
is true and you can use things like
equals equals just like I have here and
then inside of that block inside of here
you can render something in particular
so let's go ahead and render that
something in here and you know what I'm
gonna throw in another little conceptual
thing that we'll take a look at later
let's just say add twenty two so I've
got a straight arrow also known as a
straight line also known as a pipe and
then we just type out ad :
and then whatever number we want to add
so we do that and then we refresh in
here and I've got stuff rendered out so
notice that the third iteration goes
twice now this is because I have my if
statement but then I also have the
default or what I used to have now what
we actually want to do is instead of
having the default like that we would
just say an else clause in here and
bring in that else clause just like this
that way that the list can be iterated
through and if ABC is equal to three one
two then it's going to render that out
and add twenty two to it so we saved
that and we refresh and now it's still
only those four items except that one
condition is now met and it's allowing
us to do some addition now we can also
have another condition right so if I
came in here and wanted another
condition you might be tempted to say
something like else if but in Django its
Elif just like that and that's how we
would do another condition so we can
check that other condition now let's
just say if it's equal to ABC or that
single string
so if it's equal to ABC we can keep that
for loop counter in there if we want or
we can say this is not the network ABC
there we go nice little ways of doing
conditions and you probably are
wondering like what the heck is this
what's going on here that is actually
called a built-in template tag filter so
every single one of these items is
called a it's it is a context variable
but it's a template tag itself it's like
rendering something out that's specific
to the Django templates and the
templating engine and all this does is
it does a very basic function on that
context well we'll play around with that
a little bit more in the next one
by now we've used several built-in
template tags that are provided by Jango
we've used extends that's a template
tank we've used block we've used for
like the for loop we've used if but this
isn't it right we've actually have a lot
more if you look at the documentation
itself there's a whole list of items
that you'll see for built in template
tags themselves you know we just talked
about block but there's one for comments
so if you want to write notes you can
write comment as a template tag you can
cycle through things that's something we
haven't actually covered but it is
something that maybe to play around with
or if you want to see it in particular
please let us know in the comments I
don't actually use cycle that much
anymore and I'll explain why in just a
moment but we've seen for loops we've
seen include we've seen extends right so
we have all sorts of items in here that
allow us to make our templates that much
more valuable and then there's another
thing that I kind of teased that we'll
talk about right now which is filters so
this is a filter all it does is take
whatever this value is or whatever the
template context variable value is so
any of these things can use filters
basically a rule of thumb if you see two
curly brackets it's a really good chance
that you'll be able to use just a pipe
and then some filter there and yes
there's a way to make custom filters as
well so if you have a if you have a need
to see that please let me know in the
comments and here is the built-in filter
reference right so we have all sorts of
different values notice that you can add
numbers or even a string that represents
a number you can add variables so if you
passed in a different context variable
and you wanted to combine them together
you could do that we can do stuff like
slashes or cap first cap first is
probably a really good one for let's say
for instance in here we changed my text
to being title right and then back into
our actual template we would change this
to being title and let's let's just go
ahead and bring it into an h3 tag we put
title here and then we would use that
filter cap first and we close off that
h3 and all that does
it ensures to us that that first text
item is capitalized so if I said ABC
this refreshed and there we go pretty
cool now luckily the documentation gives
us a lot of examples of using this right
so like when would I actually use value
of center right so if I wanted to use
center I can honestly say I don't think
I've ever used this template tag um
that's why the documentation is there
but let's go ahead and use Center and
try it out if i refresh oops we have two
extra curly brackets in there sorry
about that
Center it actually doesn't render
anything for us because of how templates
work but it you know so I mean the HTML
I think does have extra spacing no it
doesn't do anything so it didn't do
anything but what you can do is you can
absolutely use two things at once so I
can say camp first right so I can filter
that to camp first like it does but then
maybe we use the upper case with just
upper so slash upper and all that's
gonna do is capitalize the first letter
and then upper case all the other ones
alright so we can stack those filters
together which is kind of nice now I'm
not sure exactly when you're gonna be
stacking these together like this but it
is possible
another thing that's possible is
something called safe so when you pass
in HTML as a context variable let's say
my HTML and we said hello world by
default when this is rendered alright so
I want to render out some HTML in there
when it's rendered it's rendered as just
plain text right so it doesn't actually
render the HTML document all right so we
can actually use a filter in here called
safe so we can save that and there you
go it actually renders that HTML and
there's a lot more like truncate
characters right or title look at hey
that's pretty cool so how about we do
that we've got cap first and then title
so title and title a title it title
eise's the entire title they
variable right so this is the variable
whatever that is is the variable and
then once you put those pipes there it
turns into the filter name and that it
might be cool so we can do time until so
using dates stuff that's a little bit
more advanced than where we're at you
can change the time you can change the
format of time you can strip HTML tags
right so we see here we just got strip
tags before it it's safe if I did strip
tags save that
refreshed hey there you go it's no
longer showing what that hTML is so
those are kind of the reverse of each
other one actually renders it the other
one just gets rid of it these are pretty
cool very useful inside of templates
themselves
slugga phi hey that's another really
cool one slug of five what does slug
apply do well we refresh in here it
turns hello world with the h1 tags in
there still into a slug version of it or
like a URL safe version but I can also
do strip tags and then slug of hi and
hey what do you know it removed all
those HTML tags and solidified it at the
same time so you're gonna want to go to
the documentation for this whenever you
think like hey I need to do X Y or Z
because the they're very specific to
just generally what you're using right
so if you have user-generated content
and you want their titles show up as a
title then you might do that but
honestly you might leave it as is you
might not enforce those things and
that's something that's really cool
about these template tags is you get a
pick and choose on when you want to use
them I don't actually think that you'll
end up using them that much honestly
because as we see here I'm showing you
that they exist but oftentimes when you
have values like this you'll do that in
the view or if you have something like
this also would do that in the view and
in fact safe should itself be done in
the view with something called mark safe
but that's actually not something we're
gonna cover just yet that's a little bit
more advanced but it's something worth
noting okay so that's it for Django's
built-in template tags and filters now
we're definitely ready to start render
content from our back-end so the data
that actually has been stored in our
database
now it's time to actually render data
from our database but before we do that
we have to just play around in the shell
a little bit so we can understand how to
actually access that data in the first
place before we render it out so to
access it let's go ahead and jump into
our terminal and I'm in the root of my
junior project where manage type is I do
have my server running but you don't
necessarily have to do that let's go
ahead and jump into Python made up UI
shell also I'm assuming that you have
this exact model our product model you
can have any model you want but make
sure you have one model and I'm gonna go
ahead and import that from products top
models import product okay
so if you're not familiar with how these
imports work you might want to go back a
little bit but basically we're going
from that app looking in that model
module model module that's a mouthful
and then we're importing product and to
get any single product item we can do
product that objects that get and then
we want to use an ID fee like argument
here so ID equal to 1 I hit enter and I
get back whatever that object is now I
can set this to a variable itself so
let's say oh be J equals to that and
then in here I could do something like
dir obj to see all of the different
things I can actually hit on this right
so there are there are other intuitive
ways on how to do this but this is maybe
a natural way if you're familiar with
Python you would just use dir to see all
of the methods that you might have on
here or attributes that you might have
on here one of them is ID one of them is
price title summary right so a lot of
these are unique to my model and of
course that data is also coming from
here but and a lot of built-in things
that Django has itself in models top
model so realistically you'd probably do
obj dot title or something along those
lines right so obj dot title is unique
to this model and it allows me to grab
the title that I've saved in the
database so now we sort of understand a
little bit more on how to actually grab
some data hopefully you're wondering
where the heck did I did come from and
this get call will explain that in a
little bit but let's go ahead and exit
out of the shell for now and let's go
ahead and create our first view where
we're rendering out this actual data so
whatever this data is so open up my
views inside of the product app again
and I mean the reason I'm moving it out
of the view of this other one if you've
been following along has to do with
congruence right so you want to make
sure that everything related to your
products is inside of your product app
so if you're rendering out a view that's
related to one product that should
probably be in your product gap there
are exceptions to that but just keep
that in mind so all I'm gonna do here is
say death and I'll just call this
product detail view without getting into
too much explanation just stay with the
naming conventions that I have so like
product underscore detail view we're
gonna show one product that's what we're
calling it a detailed view and I'll go
ahead and put in the request here and
then it returns render and it takes
request some template name and then some
context so of course we have to create
our template itself so let's go ahead
and write product slash detail HTML
right so I did add a slash now if you've
been following me you haven't seen that
yet so we're gonna talk about that in
just a moment and the next thing is the
in the actual context here so I'm gonna
go ahead and do from dot models I'm
doing a relative import here so from bat
models import the product class and this
is where sometimes people get a little
bit off first of all they might name a
function like a class so don't uppercase
functions keep them lower cased secondly
you might put something like product
here that's not a good idea just make
sure that it's explicit to what it is so
we're looking at a detail of a product
that's out why you want to put that
product view there so just like in the
shell we did product that objects I get
ID equals to one now there's a really
good chance that this was an error for
you and I'll explain why we jump into
the admin so let's go into our admin
and we go into products I actually have
two products in here right you might
have a lot more or you might have zero
but my model actually has some items in
here so if I click on this first one I
see there's a number right up here that
is actually the ID we can also look at
the other product that's the other ID
one two but if we look at our model
there is no ID here well that has to do
with Django's built-in features one of
them is that it has an auto incrementing
ID which you can see in the migrations
in the initial file we see there's this
ID of auto filled so it automatically
creates that for us we don't have to do
anything
another win for Jango okay so how do I
actually create the context here right
so the context is just an empty
dictionary by default and what context
do I want to put in here well I can put
stuff like title and again that was obj
title I can put stuff like description
and obj dot description right you could
you could fill out the rest on whatever
you want to show up on the model this
context again goes into my template but
I actually have to create that template
so without getting to to advanced level
stuff of where we can locate or load our
templates which I'll talk about
literally in the next one we're gonna
make a new folder in this template
folder here called product and inside of
that folder we're gonna make a new file
called detailed on HTML that's all you
have to do so if you want to have
directories inside your templates you
just make a directory in there and make
sure you add that slash put it the same
slash as that way regardless of what
system you're on it should still work
okay cool so we've got detailed on HTML
and with detail we want to extend so
extends based on HTML of course this is
continuing from previous video so make
sure you watch those and we do block
content and we do just in block there we
go
that's standard we've created our
template let's go ahead and make sure we
import our view to our URLs
so in our URLs we're gonna go ahead and
import the product view so they're from
products views import product detail
view that's the name of the view of
course and then finally I'm just going
to go ahead and make a new path here and
we'll call it product and it just takes
in product detailed view cool
and I'm just gonna go ahead and do an h1
here and say item okay so let's go back
into our project go into product cool if
you don't have this stop
go check the code against github do all
that like I just breeze through a lot of
things because we've already done this
but what we haven't done is seen how to
actually render out some objects data so
like some database objects data in this
case I actually already did it so you
might already intuitively know hey I can
just do curly brackets title here and
then I can do you know something like P
tag description here and so on okay save
it refresh in here we've got a new
product looks like I don't have a
description so I don't need to worry
about that but of course this is a good
opportunity to use a condition we could
say if description and then we'll just
render out the description otherwise
we'll say coming soon or rather probably
say something like description coming
soon and they're real perfect so again
if description is not none I mean you
could do all sorts of like conditions in
here that work in Python as well so
those are Python conditions or sorry
it's not equal like that in this case
it's not actually equal to none so we
would want to say and description is not
equal to an empty string which it very
well could be
and that
what it was cool a little bit more about
conditions that's something that's great
about watching these tutorials and
building something real okay so now that
we've got that we've actually rendered
out our template we've rendered out an
object but there is one thing that's
really disadvantageous to this method so
if we look back into our view what I
have to do is I have to map my objects
context right so every thing that's in
my objects meaning every field here I
would have to map it to the context
itself that's okay but it adds an extra
step like it meaning if I ever change my
model or I want to have new data in my
HTML I also have to go in my view and
that's a little inefficient so what we
want to do instead is instead of all
this just get rid of that or let's just
comment it out I'll leave it in there
for for reference for you guys so we do
content and we say object is obj so that
now the context object is object right
so the context variable is object so
inside of our detail here we could then
just do object ID title object
description object of description object
our description yes I will promise that
I won't repeat that again and then
object dot price right so now I can
actually change my template whenever I
want and not really worry too much about
this detail view right oh we got a we
got an error what happened object a
title sent out the name it is title so
object should be in there should have
rendered but perhaps we didn't save our
view we didn't okay cool so this is now
rendering that stuff out all from the
database really cool and of course you
can play around change things do all
that
you might recall that when I said to
create a django app when you do that you
want to keep as much about that app
inside of that app or that components
directory right when you do this you
make things nice and simple so you can
use that app in other projects that's
often the goal I mean if you make a
really really good blog app for example
you can reuse that over and over again
or even release it as a third party
package that other people can use as
well so if you end up doing that then
that means that you're gonna have to do
additional configuration for it
now this gives us a really good
opportunity to talk about templates in
that context so I've purposely left this
out because I wanted to show you how to
render out some data about that app
first and then move the templates around
now inside of our apps we can actually
put a new folder in here called
templates so inside of the sub app you
can have a new folder in here called
templates and you can do things inside
of that we can make a new another new
folder and there that new folder is
going to be the name of our app so just
like in this templates we did products
detail we would do that same thing here
and in fact we would name it exactly
like our app and in my case I did
product first so I'm gonna name it two
products and then we will call this
product underscore detail dot HTML so
we've changed a couple things about our
template I will copy and paste that
entire template itself bring that in
because we will see some difference so
I'm gonna just call this one in app
template with that title there all this
is for is illustrating the difference in
understanding how Django looks up
templates themselves so we save this and
in our view I'm going to change this to
products detail not the exact thing
because I want to show you something you
can jump ahead and go to the exact same
but I want to show you something so if I
save that what's gonna happen is I've
rendered this page out and I get an
error saying template does not exist so
this is actually pretty important to
understand because a lot of times you
put templates in the wrong place or you
have a
spelling error or something like that
this allows me to see what's going on
and we've got this temper template
loader is showing me how it's actually
loading my templates so the first thing
that it looks for is the file system
loader this right here believe it or not
comes from one of our settings so if we
go into that main configuration settings
and where we actually set up this
template ders that's what that is that's
all that is so if I had actually written
out the path to that that would show up
so if you were on the wrong system you
would see the wrong path here right
thus we make it like this the next thing
is you'll see a few other places where
it's looking it's looking in Django site
packages contrib admin templates
products detail it's looking inside of
the admin app that's built into Django
and then finally it makes its way down
to the actual app loader so it looks
inside of our own app inside of products
templates products detail of course
that's not the actual name the name that
we changed it to was product underscore
detail so if I save that and refresh
everything looks good but let's keep it
as product detail for just a moment and
just uncover how cool this actually is
so we're gonna actually look at the
Django package itself inside of our
project now do keep in mind that we do
not want to change anything in here
we're just looking at it for
illustration purposes only so we go into
Lib Python 3.6 site packages django the
just the single django not anything else
and then what i mean if we trace back
what's going on we see contrib admin
templates so contrib admin templates and
here are other templates actually let's
look at this admin app itself this is
actually not a whole lot different than
what we have there's certainly more
things there than what we have because
we're still doing a lot of basic stuff
but I mean at some point you might not
have ever
an app with this much stuff so that's
not really the point
the point here is it's the exact same
thing it's the same Django app with the
admin or the built-in app as it is with
what we're doing that's pretty cool so
you can actually see the templates and
you could edit them here but you don't
need to in fact what you would do is if
you want to override any of your
built-in templates or any of the app
templates if you want to override
something like this you would then just
put them in your file system ones you
would put them in here with the exact
same path so let's go ahead and change
the view back to being the actual proper
one so its products write product detail
that's the end-all-be-all that we want
so we see that it says in app template
now if I wanted to override this
template or any templates for any of
these apps I would come in to my
template folder that main directory that
I created and I would rename or add the
same path that I had before so I'm gonna
rename this to product detail okay
so now it completely changed that
refresh in here and there we go so it's
actually showing me the og template
right and that's how you'd go about
doing this but do keep in mind that when
you're working on your own solo app or
you have a team chances are really good
that you're gonna want to keep it inside
of this itself so I'm actually gonna
completely delete this folder I don't
actually want you to get confused about
it that's why it's gone but I just
wanted to illustrate the purpose of how
all of that would work with your
templates and how you would load them
and I think it's critical to see it
inside of map versus in any other form
because really everything about this
product app at this point is inside of
this with the one exception of the URL
of actually bringing it into the Django
project itself but that's not any
different for any of our apps including
the built in one like admin app if I got
rid of this that app is no longer
well to Jango I mean it's still working
but it's no longer accessible to our
main project so that means that it's a
very reusable app and that's the theme
here we want to keep that up
you see we want to actually be able to
allow our users to save data in the
database and they really wouldn't use
the admin or the Python shell to do that
so this one we're going to be breaking
down the basics of using Django model
forms so what does that mean let's
actually take a look now inside of any
given app I'm gonna go ahead and make a
new file here and call it forms pie do
keep in mind that this works for any
model not just the one we're using so
we're gonna go ahead and do from Django
import forms and they will do from dot
models we're gonna import our model
which in my case it's product right and
then I'm gonna make a new class in here
and I'm gonna call this class product
model form or really I would call it
product form or product create form
those are a few different names that you
might end up using so we'll just leave
it in its product form and we call it
forms dot model form and all we have to
do here is do class meta-model equaling
to product and then the fields like the
actual model fields that i want to have
in here like you know which ones of
these do I want well it's just you title
and description and price okay so title
and then description and then price okay
so we now have our model form all I have
to do is render this out in a view so
let's go into a view and let's import
this so from dot forms import product
form and I'm gonna make a new view
specifically for this and I'll just copy
this detail view real quick and we'll
call this product create view I won't
worry about the object itself alright so
the context that I want though is I'll
just say form equals to product form and
then we'll just initialize it with
request dot post or none
that's a worry if you don't understand
what's going on here in a few videos or
the next few videos we are gonna go into
a lot more depth here so just just bear
with me
so if form dot is valid that's another
thing that we will end up doing I'll
just do form not safe okay and I'll go
ahead and add in this form here into my
context and I'm gonna make a new one
called product create a CH tml so that
means I need to make that template
itself and by now you should absolutely
know how to do all of this right and the
simple way to do it is just copying of
course our other template and then in
here I need to create a form element or
a form HTML element and I'm also going
to do input type equals to submit and
we'll say value equals to save don't
close that off and then inside that will
just do form dot as P so this is a
built-in method that turns the form that
we are passing as context into a actual
HTML form rendered out with paragraph
tags we'll take a look at that code in
just a moment but now that we've got
this great view let's actually bring it
into our URLs so into URLs will import
this in and I'll just go ahead and make
a new path for it
I'll just call it create and it's gonna
be the product create view okay
so again let's make sure everything's
saved all across the board forms
templates all that stuff let's go ahead
and look in to this create and here we
go we've got our form rendered out here
with the actual fields that we specified
so I'll just say new product this is
awesome and some price right doesn't
really matter I hit save and I get some
error here right so I've got this stuff
up here it's not really an error it's
just I didn't actually specify the
method that I'm using on the form itself
so back to my template we'll go ahead
and say form method equals to post and
we're also going to add in this CSRF
token
okay these things we will absolutely
discuss when we break this down and go
from bare minimum I just wanted to show
you how to do it first hopefully to
pique your interest to learn a lot more
about this that's the point okay so I
refresh in here let's get rid of all
that stuff in the URL and I'll just do a
new product again and description does
it matter
price $12.99 okay so I've got this not
null constraint failed all right so I
have an error here and that's because if
we look at our model let's take a look
we have this featured and it's required
and it's not blank that's where this
error happens this error happens all the
time which is part of the reason I
actually left it there so to actually
overcome this for now what I'm going to
do is just add in a default of true or a
default of false either way that part
doesn't matter but we made some changes
to our models so what do we do Python
Michelle py make migrations oops we want
to make sure we're the root of our
project we're python manager py is make
migrations and python manish of py
migrate okay let's try that again and
we'll say new product or new course
whatever doesn't actually matter like I
said a million times I go ahead and save
that and I can't tell if actually
anything changed so let's go into our
admin let's just log in there go into
our products and what do you know it
looks like I have more products so I've
got a new course here and then new
course here so I actually saved a few
different items of data so one way to
solve that problem is in clear out
what's in there it's really simple we
just go back into our view and we
rerender it just like that so we would
just rerender the form so then the
context will change and update for us so
let's go ahead we can literally reef
submit that same data we get this error
that's a security problem or not a
security problem but a security feature
so let's go ahead and just add in
another one
and some price we had save clears out
the form for us we go into the back end
and what do you know we've got our
product there I'm cool so we now have a
model forum so in the next few videos
what we're gonna do is really just break
this down a lot more in depth like how
do I actually build a HTML form from
scratch and understand that data that's
where we'll start and then we'll get
more and more complicated to better
understand how forms work in general and
then better understand how they work
with Django because this is certainly
not the only way to do it but it's a
fairly easy way even if it doesn't feel
like it's that easy of a way I promise
this is a fairly easy way to do it
now that we've created this product
model form and rendered it out inside of
our product create it's time to just
take a few steps back and do it from
scratch as in raw HTML and then move up
the chain so one of the first things
that I'm going to do is actually get rid
of the Django related stuff so those two
things are now gone all right so we have
only one HTML input here and that is to
save it so the first input that I want
to actually put in here is input type
equals to text and the name is going to
be title as in what do we want to call
this input I'm giving it the input
itself is a name so I can use title I
can say my title neither one of those
actually makes a huge difference which
we'll see why in a moment so we got
input type text' name title and we can
also add in something called a
placeholder where we can just say your
title this is just kind of giving them
some information we'll see what that is
in just a minute okay next thing is in
the view itself I'm gonna go ahead and
comment this one out and create a brand
new one that only renders out empty
context and no form related data okay so
we've really rate three you know just
backed up a lot and redo this view okay
so we look at this and we look at that
view let's go ahead and take a look at
it inside of create and we've got your
title here with a Save button if I type
out ABC and hit save I get this CSRF
verified failed okay now why is that
happening
well it actually has to do with our
method here so if I change that method
to get what happens i refresh and say
ABC hit save it seems like something
happened but what you might have noticed
is the URL changed you see get methods
are what is the default method for a
form so if I just typed out a form like
this
and rendered it and said something else
it will change the URL this is actually
very similar to like when you want to do
a search on your website but instead of
doing a search and you know going into
the nitty-gritty of that what we are
gonna do is keep that method of post
okay so we save that and refresh try ABC
again and we get this forbidden yet
again now this has to do with security
measures that Django has built in now a
big part of the reason for this is
something called action so if we type
out action and we set it to let's say a
different URL let's do like slash search
and let's go ahead and bring that method
up get back and I type in let's do a
refresh in here type in ABC hit save
whoa what happens it takes me to a
different URL as well as a different you
know also including that data that I
actually put in so action then means
they can send it to a completely
different URL so what if I did this same
thing with like Google so wwq Google
calm slash search I'm actually gonna get
rid of that trailing slash there and I'm
also going to change the name here to
cue and then I will just say your search
we save that and we refresh in here
we've got your search and I'll do django
CFE hit save
hey what do you know I actually
performed a Google search right there
and what's pretty cool is Cody French
Bruce came up a lot that's awesome I
like seeing that okay but what's more
important here is understanding that hey
I just created my own Google search form
which is really nice for one feature but
the other part is none of this in here
is related to Django so you actually
learned a couple things number one the
action will send the form to whatever
URL you put there now if we actually
change this method to post just like
that and now search
Django CFE let's just refresh in here
and now search that hit save we get a
405 error the request method post is
inappropriate for this URL now that
hopefully makes sense if it doesn't I'll
explain in just a second but it's pretty
cool we can actually change the action
and we can change the method now by
default what happens is the action goes
to the current URL so if you do period
here you can see it as an empty string
or period either way it's gonna go to
what this URL is pretty nice and then
it's going to use that post method so
again we're gonna change this back to
being title and your title and then we
save that and do ABC I hit save and
again I get that forbidden call once
again so to override that problem we do
CSRF token okay so we save that and we
refresh in here confirm form
resubmission we can say yes now let's
try it again and there we go
so it actually goes away so the data
seems to be going through now what the
heck is get in post
now git request is meaning that you go
to any URL so when I go to any any URL
on my page like about contact whatever
you are getting information from that
when you want to save information in the
backend we use post like kind of like
mailing a letter to somebody you post it
right this is very similar and we just
use two different types of requests to
do that now what's happening is actually
not a whole lot different like the back
end can treat both kinds of data in the
same way which we can see in our actual
view itself so our view itself has those
two methods built-in so if we do for
print request dot get and print request
dot post
we can actually see what's going on with
either one
so with get if I just refresh the page
here I see that I've got this query
dictionary that's empty and what I can
actually do is say you know title equals
to something right so I've got now I
have changed my get request because I
changed my URL I can now see in here
that I've got some data coming through
from there so this is an actual
dictionary that I could say get dot get
or you know grabbing the actual item key
value pair there and that will print out
whatever title I put in here so if I
said yeah this is a title it's gonna
actually print that out for me in the
back end pretty cool so yes you can
absolutely save this data I don't
recommend doing that using git is a
unsafe method for saving data that is
why there's a security feature for post
and that's not unique to Jango it's
certainly not unique to any web
application it's its general rule of
thumb to when you have posts you want to
add in some security now the reason why
is that if I was gonna have this title
in my url then a hacker or somebody else
can just use a link that changes it to
being something like this and that would
quite literally change the title for me
it starts to bring up all sorts of
security questions that you may have so
instead of doing that we use request
post right so I'm gonna get rid of this
part of the get call and then inside of
my form I still have it at post so I can
get rid of all that and do ABC hit save
and now what I see is all of that data
coming through
pretty cool so that means they'll the
very last part of this is I can actually
come in here and say title equals to
request that post that get title and I'm
using doget for the dictionary itself to
grab what's in there and that's going to
be the title I would use
and then I'm actually not gonna save it
because I don't want to put all of the
information in but if I did product dot
objects that create title equals to my
new title right so my new title and then
I had every other field in there I could
then go about actually saving that
requested post data which is denoted by
just printing out that data itself right
and getting rid of these request methods
here okay so it save ABC and save and
there we go we've got our title being
printed out now let's go ahead and save
it again and try it one more time not
refresh ABC we hit submit and all I see
is ABC at the very first I see none now
why is it that I see none at the very
first is because we don't have any post
data by default so there's a lot of
things that I still need to dive into
when it comes to this but what I just
showed you is how you would write a raw
HTML form in Django and then just
generally how you would create the data
from that there's one thing that you
could do is say is if request dot method
equals equals to post then you can run
through and do all of that stuff and
that's okay so that's asking for the
method whatever that method is will give
you you know get post or a few of the
other HTML methods and then you could go
ahead and save it and then that way when
you refresh on that page it won't say
none first like it did right instead it
will just only render out ABC it says
none there cuz I copied and pasted it
but let's just hit enter a lot and just
illustrate the point
I refresh that page I got my get request
there I do ABC it save I got my post
request and the actual post data cool so
if this is unclear at all you might want
to look into more about HTML forms
themselves please let me know in the
comments but this is really a bad method
of saving data it's really really poor
because we're not validating
if this is good data at all we're not
cleaning this data so we want to make
sure that we do that and that's another
topic that we need to discuss and we'll
do that in the next one
um so I'm actually going to again
comment all of this out copy it and
paste it over
probably should have copied it first but
you know whatever
okay so again I'm gonna go ahead and
delete all this because we're basically
starting from zero or as if we were
starting from zero okay so I've got my
view here and then I want to open up
forms again just go ahead and ignore
this for now but it is not a bad
reference so I'll just go ahead and say
class raw product form and it takes in
forms dot form so it's not model form
just standard django form so with the
standard Ginga form we have to declare
our inputs so in my case I've just been
using model but I can go further than
that and we use form char field and you
know we can say description and we'll
also do form char field as well and then
we will say price and forms that decimal
field so these should look very similar
to our models and that's because they
are so we've got our decimal field char
field and our we don't actually have
text field so if you try to do text
field it's not going to work I'll
discuss that later but we'll just do
char field and honestly if you wanted
some reference for that you just do
Django form fields and it should give
you the field types in here
all right so form fields all of the
various field types are in here so you
can absolutely use any of those but you
know text field is not there so these
all render out a specific look by
default so if I grab this form bring it
back into my view and or bring it into
my new view now I'm back into it we have
to render out of this form so to render
it out we create an instance of the form
so we'll say form is that this creates
an instance of that form as you may be
familiar with Python and how you create
instances from a class we add that form
into our context
okay so again we could say my form here
and then have form there we're still
going off that product creates so back
in that HTML I'm going to get rid of
this here and just you form dot as P so
this renders it out as paragraph text so
if we save this and take a look there
let's just refresh that page I can
inspect the element and take a look and
see that hey we've got our form we've
got an action we have our CSRF
middleware token that security token we
have some P tags in here and that's as P
those are the ones like as HTML or no
not as HTML but as Li or is it ul
something like that yeah there you go
so you can render it out as UL it is
HTML so as HTML does that make sense
but SP is a way to render it out and now
we have a form with some data so I can
add in whatever I like right and hit
save now naturally what just happened
was we submitted the data to our form
here or at least it seemed like we did
but we didn't we didn't do anything
right so this form itself is just
rendering now it's not actually getting
any of that data and that's why we use
request dot post here so if I save that
just as is and refresh in here well it's
just a refresh in this page and I see
that now it's giving me these validation
errors these are called validation
errors this is awesome this is built
into Django right away it's already
validating stuff for me unlike the HTML
the HTML absolutely was not but it's
asking like well why our validation
errors even happen happening at this
point right so we see that this field is
required but how does Django already
know that well it has to do with what I
initialize it with so I have it in as
request post so let's make this work
using kind of a long way at first will
say if request dot method equals equals
to post
so again that's built into the request
object itself that's being passed so if
the method is equal to post then that's
going to be my form I'll actually use
that data in my form in other words I'll
pass in that request post data as I
initialize my form so I also have to
initialize the form by default so I need
a get method for it and that's where
this comes in
right so I render it for the get method
so I can see what it looks like and then
with the post method which is a
different type of request which means
that I still have to render it for that
different type of request so we've got
this is roughly requests that get right
so that's what is passing in by default
but requests I get doesn't have anything
probably so we'll go ahead and leave
that out and now this will actually
handle my form data so if I save this
and the Refresh in here and hit save
it's now saying please fill out this
form and that is based off of my browser
and see that it says required there so
if I actually removed that right so I
literally removed it from the code in
the elements you don't have to do this
this is more illustration purpose and
hit save it just moves to the next one
so again I remove that and then the
final last one all those requirements
just remove it and I hit save Gengo now
does the validation for me right so I
actually showed you a way that a user
could potentially disrupt some of your
raw HTML forms and that's where Django
security comes in not just for this but
also for this right so I absolutely need
all of those things working so I had all
of those fields required and this is a
way to actually validate it this does
the validation so there's a method
called if my form that is valid this
will actually say hey you have a valid
form you know now the data is good and
I'll explain the data part in just a
second but now that the data is good
we'll go ahead and print out my form dot
clean
and data so this would be the data that
actually comes through from the form
after it's been validated okay and then
we could also say print else my form
errors okay so we've got those two
different methods so if it's valid then
it's going to do that if it's not valid
and then it's gonna print out what those
errors are oftentimes you won't
necessarily need this because the form
itself as we've already seen renders out
the problems that might be related to
that form and that's because of this
right here too so a lot of built-in
features going on here that we're just
not quite breaking down just yet so
let's go ahead and take a look at this
let's actually put in some valid data so
we come back in this create method I'll
say ABC you know whatever and whatever I
hit save and nothing that form doesn't
rerender which will solve that problem
in a minute but if we look in our
terminal we see hey here's our clean
data it actually gives us that data and
that air list digit show up as well
because we resubmitted the form and
there were some errors okay so what is
another thing that we could do that you
know would potentially cause some
problems what if I change this price
field well if I go to inspect element
change it change the type in the actual
HTML to text all right so now I can
actually type out text type out text
type out text I hit save hey it's got to
be a number
so that's other built-in validation that
our forms actually have right so from
this data let's actually save an object
let's actually do something that you
would end up doing right we've got a
product that objects that create and we
have some of that data that's coming
through right we have a dictionary of
this data and it's doing title
description and price right I named
those fields on our form that way on
purpose it was to match our model and
that's what you should do as well
because again we're working towards this
model form and we're doing the long way
we're understanding more as to what's
going on
so now that I've got that I've got this
created here well what if I actually
just passed in this data so let's go
ahead and pass in the clean data here
just like that so I'm going to create it
from that clean data so let's go back in
here and I'll say new title some
description you know some price I hit
save and I get an hour I get an error
here right so what we can do is actually
use the two stars here and that will
turn this into arguments that we're
gonna pass so let's try it again I had
saved no errors let's look at my
back-end and I've got a bunch of new
products with that exact same name cool
so I actually were was able to save some
data from my raw Django form that does
some validation for me now there are
parameters and things that we can set in
here there's definitely a lot more that
we can do with these fields including
rendering out how this description works
so we're gonna dive a little bit more
into that in the next one
now what we're gonna do is things
related to any individual field like
let's say for instance you want a field
to not be required or you want to change
the label of it or whatever input is in
there by default so if you take a look
at your forms and themselves we can
change a lot of things very simply do
you want this field to be required well
just type out required true or false
right obviously with the title I want it
to be required and that's actually the
default so really you don't have to
write out whether or not the default is
true you would just say false now of
course you might be wondering how do I
know where the defaults are of course
the descriptions on the documentation
for the core field arguments will tell
you what the defaults are like required
the default is true it's in here
somewhere the next one is changing your
label so if you want the label to not
even a pure just make it an empty string
it's a very simple way to do it and like
something like price you can also set an
initial value so initial equaling two
let's say for instance 1 9999 okay so
that's a simple and easy way to change
those 3 initial arguments to any given
one of those fields if i refresh in here
there we go
it actually shows us for that so more
more specifically not necessarily
refreshing but just going back and
rear-end during the page this number is
actually in here so there's absolutely
more things that we can do in here as
well like notice that I don't have any
placeholders well and also the
description itself is not rendered out
as a text area so let's do the
description first and we'll change this
to being a text area by overriding the
default widget by putting widget equals
two forms dot text area and that's it
I'm refresh in there it gives me a text
area now you can look up all the various
widgets also on the documentation for
the forms because there's definitely a
lot
in there and you might end up changing
things like a textarea and perhaps you
want to have even bigger or larger
changes to that that particular input
and we then just put in some parentheses
here attributes equals to another
dictionary
so since I'm really overriding a lot of
this I'm just gonna go ahead and
separate out some of this so I can more
clearly understand what's going on here
first attribute that I might have is
class like maybe you want to set a new
class name here new class name or
multiple classes right too
you can also set the rows that you'd
have on here so let's say we did a
hundred rows i refresh hey that is a big
forum there right of course that's
probably not likely maybe you do
something more like 20 and have a bigger
text area and of course you could do
columns as well okay and of course if I
inspect this element here I see that hey
I've got the name here I have the two
classes that I added and then I have an
ID what if I change the ID in here my
dash ID for text area
refresh in here up you need to make sure
I put a comma at the end of that I said
it is a dictionary
I now see them ID has changed so any
different attributes that you want to
put on there you absolutely can and
that's a very easy way to do it now you
can also do it on the title tag so we
wanted to say that we want to put a
placeholder here so let's go ahead and
do forms dot text input this is the
default widget for the char field so we
would just change that to being
attributes equals two placeholder and
whatever you want the placeholder be so
your title say that and we refresh in
here what do you know your title is
showing up of course that placeholder
you might also want to have that inside
of your text area so your description
and so on right so that is how you
override some of the basic things about
the form itself this also changes how
the foundation works just slightly at
least for the required right so if I try
to save it and I type out some of the
other ones the descriptions no longer
required so it's no longer going to show
up where the price and the title are
required so if I get rid of the price it
will tell me to fill out this fill field
itself and that of course is the web
browser doing that so if I did that
little hacky thing where I got rid of
the required element on here and hit
save again it gives me that same
validation so that's pretty cool but
it's only giving us a little hint of
what validation actually is so this part
is well we're actually pretty much
identical to this product form at this
point the forms themselves aren't any
different in the sense that the model
form renders out the same sort of stuff
in here the only difference is how the
view handles it that's it
you might remember we just did the form
itself and then we just saved that data
this is actually doing roughly that same
thing so now going forward we can render
out new types of validation for our
forms so let's go ahead and do that and
and the next one
Django has a lot of built-in validation
for its fields so when we render out a
Django field or Django form we actually
can submit some data and Django will
check to make sure that data matches
that built-in validation so if we take a
look at the model form which is now what
we're gonna use I'm gonna show you that
it's really simple to override the field
themselves right so if I actually bring
this title in over here I see that this
is the same name as that one so that's
actually how you override what comes in
by default kind of a cool little feature
to have so now what hopefully you
realized and I did mention in the last
one but now these forms are actually
identical they have the same three
fields the only thing that's different
is how the view handles them that's it
but we're going to go back to using that
product form itself so I'm gonna go
ahead and comment out all of this and
we'll come back into our original
product create view that we were using
okay so what I have here is a shortcut
method to what I did up here right so
that request post and then render these
things out all this does is renders out
that form if post data comes through
otherwise we'll just render out an empty
form that's all that's going on that
right there okay cool so now that I
understand that what I want to do is
take a look further with this is valid
related stuff so let's go ahead and take
a look make sure my form is coming
through a refresh in here and I've got
my price my field was required so it's
possible that I might need to save a few
things here let's make sure everything's
saved up we've got our forms there we go
and we refresh our title goes away and
if I go back on the create it shows me
that I have my placeholder there so yes
I could absolutely just copy all of
these things in here as well
and once I do that I have a more robust
form in the sense of how I want it to
look and almost how I want
to work so so when you do this you
realize that you did change quite a bit
and yeah there's absolutely shortcuts to
doing this there's third party packages
that do a lot of this stuff for us which
we're not going to talk about yet
because it's getting a little bit too
advanced but instead what I'm gonna talk
about is like what if I want my title to
be you know to contain a certain word
let's say I wanted my title to contain
CF e right so that word itself or that
those initials itself what I need to do
here is come in and say define clean
underscore then my field name so
whatever field that I'm gonna be
grabbing the validation for this is what
I want to do clean title right so I want
to make sure my title has a specific
item in there so a just say self and we
can do ours and keyword ours
those are probably not necessary but
oftentimes if you're not sure when you
override something just make sure you
put args and keyword ours so to get the
actual title itself we do self dot
cleaned
data dot get title okay so this is gonna
get the default title this is gonna get
the post Jango form cleaning so Jango
will clean the form itself initially and
then it's gonna trigger this title in
other words this is not overriding
required for example that required will
absolutely still be in there and to
validate this we just are going to go
ahead and say if title or rather if CFE
in title then we'll return well do we
want to do it this way right so let's
let's just do the logic first
so if CFE is in the title then we'll
return that title whatever that default
is otherwise we'll do forms dot or
rather raise forms not validation error
this is not a valid title okay so we
save that and let's take a look refresh
in here I'll say ABC hit submit hey this
is not about
title there is our validation it's
really really simple I mean it's not
that advanced or that complex and of
course I actually wouldn't write it in
this format what I would do instead is
say if not in that title then raise the
validation and the default returning
that title now the reason for this is so
I can have multiple validations if I
wanted to if news is not in the title
not a valid title right so ABC space we
got two not invalid well let's actually
save and refresh this let's do that
again
so I say ABC I hit save I've got this is
not a valid title ok so right off the
bat it will raise that one now assuming
that I put CFE in here like that
and hit save again it's gonna say not
about a title so it would have to
validate all of these conditions that
you might have and of course these
aren't realistic ones for a title this
would probably be more realistic for
like an email so let's say for instance
if I did clean email and we did email
I'll throw in this email in just a
second the actual field itself so let's
just go ahead and say if not or rather
if email ends with that II D U or if not
ends with edu then we'll do Ray's forms
validation error this is not a valid
email then we can return that email and
since I'm doing this this is a new
little feature that you might end up
using is you could say email equals two
forms dot email field notice it's on the
model form it's certainly not on the
model so you can refresh in here I got
my email filled in there I say ABC @
gmail.com I hit save not a valid email
so it's pretty cool validation is fairly
simple and then you can run you know any
sorts of validation things on here now I
will say that doing
nation is not only on a form but since
we've been working in these forms it's a
really good way to introduce validation
as a concept you can absolutely do
validation on the fields for a model as
well but the idea for validation works
whether it's a model form or just a
standard django form and what you should
see or hopefully this pattern that
you're noticing is that if I commented
this out and change this to a form the
form itself will render the exact same
all of the validation will render the
same all of that but of course the one
caveat is how the actual form would work
in the view it is slightly different
so to set initial data on a form all we
have to do here is create a dictionary
so like initial data set that equal to
something so what are we setting it
equal to it's going to be the names of
the fields inside of the form so looking
at the form we have our raw product form
here we would do title description price
any of those things we would set the
initial data here so it of course is
outside of a form itself because it
might change based on your view so this
is my awesome title something like that
and then we just pass it in to our form
so we just say initial equals to that
data and again we can use any of the
fields that are in there so if i refresh
in there what do you see we've got that
initial title in there it's not a
placeholder it's literally the same text
or it's the actual text that's in there
now I don't know how often you're gonna
do this in a raw Django form more likely
what you'll do is do it in a product
form or a model form itself so if I
changed it to a model form the data is
not any different it still looks exactly
the same and that's because model form
is not a whole lot different than a Jago
form so if I actually added one more
attribute to this and that is actually
changing an object that's in the
database so to change an object we want
to grab that object first so product
objects that get will say right now will
say ID equals to one so we still have to
look up dynamic ways of getting these
objects we haven't talked about that yet
but to actually change one with this
form all we need to do is pass it in as
instance equal to whatever that lookup
is so in this case it's just obj so now
what I can do is take a look at that
object so I still have initial data
there let's look at the price though if
i refresh in here I see that the price
actually changed although the initial
title didn't usually when you're editing
something in the backend you're probably
not going to have that initial data come
through instead what you'll have is the
actual title itself and of course the
final step to make sure that you can
edit it is first off doing is valid form
is valid and then you can just do form
dot save okay so
refresh here and I'll just say product
instead of product title and I'll change
the price to some ridiculous price I hit
save seems to be working
we'll just double check in the admin to
make sure that it is we look in our
products
the very first one because we were going
off of that very first one we see
product and we see that new price it
works that's how you set initial data as
well as editing model form data
now we're gonna change our content based
off of the URL otherwise known as a
dynamic URL so first of all we're gonna
say object equals to product objects get
ID equals to one so we're setting the
default so we can see just exactly how
this works so object equals to obj and
then we are gonna render out this basic
template from this basic model and then
finally in our URL this is what it looks
like but we want to do is make it
dynamic that is I want to be able to
pass in an ID here so if I put in one or
two this content will actually change
based off of that to do it we just put
in these brackets here and then we
declare the type so in my case I'm going
to use an integer you can also use STR
you can also use slog and there's a few
others I'll reference in a moment so
integer and then I'm gonna give it a
name in my case I'll say ID you can also
say my ID or pretty much anything else
that you'd like ID is default right so
that's sort of standard is using
something like ID or if you are using a
slug type you would do slug : slug but
we're gonna use int for integer and just
pass in that ID what this does is it
passes in a new argument to our view so
our view has the request by default and
it passes in that new argument of ID
which we declared the name of again if
you changed the name here like my ID you
would have to change the name on your
argument right there we'll leave it like
that just for illustration purposes but
what's gonna happen now is our object is
gonna change based off of that ID
because we're gonna pass that variable
in just like that so we saved that and I
refresh in my page I go to page 1 I get
a dynamic view I mean I need to make
sure that I save everything here but
this is an error that if I actually
didn't update my view function this is
what happens right so I'll save this and
I'll replay that error in just a second
but if i refresh in here I now see that
what do you know it's now a dynamic URL
and it's actually doing the lookup based
off of what's in the database
so if we go into our products and click
on any of them we see that it's also
doing that same sort of lookup granted
the URL is slightly different but the
number is iterating so again if I
actually change this to ID and refreshed
in here I get this problem this dynamic
lookup or our view this is really just
our view function here doesn't know what
this keyword argument is so we just have
to make sure that we put it in here
to handle a missing object from a
dynamic URL we are gonna import a new
shortcut called get object or 404 so
basically it's going to raise a 404 page
if it's not used so all we need to do
here is get object or for for the actual
model that we're using and then the
lookup parameters that we're using and
that will solve that error so we save
that and now if I go in here on product
does not exist no longer will give me
this sort of error instead it'll just
say page not found this is a valid error
there's one more way to do this and that
is putting it inside of a try block
let's do that really quickly from Jango
to HTTP import HTTP 404 this will also
raise that 404 page much like this get
object or 404 so I'm going to go ahead
and comment this one out and do obj
equals to product objects get ID equals
to ID and again I said I'm gonna put it
into a try block here to handle the
exceptions so except this is product or
the model name does not exist then we'll
go ahead and raise the HTTP 404 okay so
we save that a refresh in here again
we've kept that for for error and if I
change it to some other number still
doing that okay cool so actually let's
look at this real quick to see how I
know that this is it other than the fact
that I've been doing this so long so if
I save this just like that refresh I get
this this is an exception right there
that's an exception this is just a
simple way to handle set exception this
get object r44 is they preferred method
because it's a lot faster than writing
all of these different things out or
even just the entire try block so again
I'll just use that
deleting an object in the database is
super easy all you just type out is obj
dot delete and that will actually delete
that object but unfortunately this will
happen on a what's called a get request
right so we want to avoid that from
happening we want to have it on e well
let's say a confirm post request there
are other requests there's something
called a delete request but we're gonna
do it on a post request to confirm that
they actually want to delete this okay
so what that means is we are gonna
render out a form in here that will just
do a post request for us there's really
no data in here but all we need to know
is if they actually submit this form
that means that they want to delete it
otherwise they can go back a URL and of
course I'm using this URL pattern here
not a whole lot different than what
we've seen before okay so to do this
then we just are gonna go ahead and say
if request method equals to post then
we'll just go ahead and delete that
object so again this is a confirming
delete that's it it's not actually the
method to delete it's just confirming
that they want to so if I go now on that
URL for any given object
I hate say yes and then if I actually
refresh in here
I see that it actually goes away so the
final thing on here would be to sort of
redirect them somewhere else and we can
just do that with redirect shortcut and
just do return redirect and we'll just
go back a few pages okay or or
relatively we'll just say yes and that
will bring us back to that so we can do
something like that and that sure brings
back a couple more times and yes this is
actually deleting these things in the
database
so we delete it we say yes it brings me
back to that products where I might list
them out but this this is in the
database we now see that those are all
gone
to list out objects we first have to get
a query set and that is typically named
as query set screw set that objects dot
all that is a queer set this is going to
give us back a list of objects and a
typical context variable name for query
set is object list just like that so
that means in our variable I can
actually render out that object list and
you should know now for obj or for
instance in object list that is my for
loop inside of an object list so I can
use the instance variable inside of that
for loop to get you know my product
title something like this so instance
that ID and we'll just put it into a P
tag there we go
okay so we save that save the view save
your URLs and take a look so if we go
back into products now I see all of my
data coming through the query set
renders as well which obviously I don't
want to have happen but now I actually
have a list of items that I can see in
this template let me get rid of that
object list but something you should
notice is this right here could be
reused with any model and that's the
purpose right we want to make sure that
we can make these things reusable and
that's why we use standard names like
crew set and object list
to create a link to the detail of any
given product you might do something
like this and of course it would
actually work it would take you to the
relevant URL and path with those dynamic
URLs just fine
but the problem with this is that if you
ever changed any of these URLs let's say
for instance you change them all to P
then you'd have to go back and make sure
that all of these things are changed and
it's it's just a lot more cumbersome so
what we can do is create something
called a instance method on our model or
a function on our model that will
shortcut this for us and it's called get
absolute URL this is actually the
convention to grab the URL inside of
Django so it's used in other places but
for right now we'll just go ahead and
use it in ours so I can return the
products and whatever it is that I'm
using for the URLs using the F string or
string substitution here allows me to
actually grab whatever that URL is based
off of the instance so if I do change
the URLs I can just make sure or know
that everywhere that get absolute URL
works this will update as well so we
just do instance that get absolutely RL
and that gives me that actual URL
it's time to transition our get
absolutely oral method to being dynamic
itself as in this string right here so
if you look at a URL we actually named
our URLs on purpose we haven't talked
about them yet because it's only related
to this part and then is making this
being developed based off of whatever
this is named so to do that we use a
function called reverse come in here and
call reverse here are some of the
defaults that we use keyword ours
hopefully you're familiar with keyword
args in the sense that hey these are
keyword arguments that I'm passing to my
view so I know that I need to pass those
as well and what do I need to pass well
ID and self done ID so self is referring
to the instance of the object and then
ID is referring to the ID that's built
into it the next thing is I just need to
call the name so the name of the actual
URL that's gonna handle this data and
that is our product detail so that's the
name just product detail so we save that
and we go ahead and refresh in our links
of course all of that is now working so
that's a clean and easy way to make sure
my URLs are dynamic and when I mean
dynamic is in my URLs top high if I ever
change this to let's say P those links
would actually update right so if I
click on that it now actually updates it
as well and it does it across the entire
site everywhere where the get absolute
URL method is used which there are
third-party packages that use this as
well so let's just keep that in mind
when it comes to making this more
dynamic sure you can hard code it but
that is definitely not a recommended
method so let's leave it as products
slash
you take everything we've done so far
and just clean it up into their own
views with names that match to your app
you'll see something like this the
create view the update view I change
this the list view the detail view
change that right so you should have an
idea of how to do all this if you don't
go back a few videos now what we do is
we look at our URLs and you'll see
something like this this is related to
that but the problem comes up in two
forms number one we have this is not
actually they reusable of an app right I
have to actually import all of these
views right on my URLs and number two
what if you accidentally used the same
name and same keyword arguments
somewhere else
remember our model is based off of that
what happens well what happens is it
doesn't work as expected you go to a
different view altogether that is not
great so what we want to do then is
actually put this in to its own URL
module inside of the app that it's using
right to make that a poor usable and
also avoid situations that I just
mentioned so to make these URLs I can
actually import all of this if I wanted
or I could just do a quick import just
like this right so this is a relative
import of all the views that I have and
it's importing path and then we just
declare URL patterns back in our main
configuration URLs I can go ahead and
cut all of this out and paste it into my
URL patterns now okay so these are now
those apps URL patterns so back in my
URLs I actually have a way to use those
URLs it's right here in the comments
it's already in there so all we have to
do is import include and then bring in
the example that gives what is for a
blog app in our case we're using the
products app and we just do it like that
and then put a comma at the end and now
our URL patterns our main configuration
URL patterns are a lot cleaner and I can
actually delete the imports that are
coming through there so I say this
refresh in here I'm getting a page not
found what's going on here well it's
actually showing me the stacked level of
my URL so if I do products products it
works but that's not what we want the
only reason that that is the case is
because we haven't gotten rid of our
original path that was in there so just
getting rid of that will solve that
problem
there definitely is still one more
problem that we need to solve so we save
this and refresh I still have my
products rendering as they were I click
on this it's still bringing me to the
wrong place and this is where name
spacing comes in so if we do app name
inside of our apps URLs - the name of
our app so in my case products right you
just call it that now what I can do in
my model is just add that in here to
products : and now my reverse is based
off of the app itself or the namespace
and the URL name so we save that refresh
and now it's actually gonna take us
where it should this is a common problem
so if you have to test this out and try
it out on your own
please go ahead and do that and do
realize that having names on the URLs
doesn't mean that it's going to check to
make sure that those things are unique
so this is a way to do that I mean you
can change your products app name if you
need to and that would allow your
namespace to change and therefore your
reverse method to change as well as you
can see this is why reverse is actually
very important that's this is the main
reason is then when I want to bring this
app into a whole nother project my URLs
all I have to do is declare what they
are as the app name I have to make sure
my users know or that third party
package know hey here we go we've got
our product URLs here and along with
that namespace I realized there's a lot
going on here so you definitely don't
want to try this out multiple times make
multiple apps make multiple models do
the views do all the things that we've
done leading up to this point multiple
times on your own
the next few videos are going to combine
the knowledge that we've gained over
this series so what I want to make sure
that you can do is these steps here one
through eight and go ahead and do them
now if you can and I'm going to use this
model but you can use any model you'd
like but again make sure you do these
steps if you don't know how to do them
just go back to the beginning and start
from there so without further ado let's
jump into our views and make the
absolute simplest class face view and
that is a list view
so we'll do class article list view and
it's gonna inherit from Lois view and
with the list view I have to provide
something called a query set this is a
requirement so article cut objects not
all
that's it that's my entire list view
notice I didn't have to call render I
don't have to write a template name I
don't have to do any of those things so
with this I'm going to go into my URLs
for this app I'm gonna import it in here
and I'm gonna bring it in to my default
path for it something that we've seen
before I'm gonna bring in that class
name and then I'm just gonna call as
view so it turns it essentially into a
function based view like we've seen in
our product view page right these are
all function based views this is now our
class based view and that's how you
actually run it as a class a few so with
this now I'm gonna go into my URLs and
bring in my newly created blog URLs okay
so I've got that URLs module inside of
that app let's go ahead and take a look
at all of my posts a refresh in here and
what do I see us he's something that
says template does not exist so by
default class page views look for a
specific template and the way it looks
for them is the app name the model name
and then the view name or the generic
view name so in my case it is a list
view so it's gonna look for blog slash
model name underscore list ml this is
not any different going forward right so
let's let's actually put this in here as
just sort of reference for us in the
future so what we need to do is actually
create this I actually already have
these items in here so there's two ways
on how I can actually reference a
different template and we can say
template name equals to what template we
want so articles slash article list HTML
that will allow me to use my very basic
templates for article list right or I
can go based off of the generic one I'm
not gonna go based off the generic one I
just wanted to show you how you can
override those templates so I refresh in
here and now I've got that list coming
through
the next most simple class-based view is
well it's our detailed view I'm actually
gonna copy the article list view and
just change it with detailed view and
just like that copy this bring it into
my URLs come in here I'm gonna keep
these things in order this is just
personal preference okay and then down
in my URLs I'm gonna replace the detail
just like that and I'm gonna change the
keyword argument to pk I've got my
template here already it's very simple
so I'm going to go ahead and go in to
that first article that I have there it
is not really that hard to do it's
actually very easy to do so of course if
I didn't override the templates what
would happen I would get something like
this and if I change the keyword
argument to back to ID what would happen
I would get something like this so you
can absolutely have your own lookup if
you want but by default it's looking for
the keyword argument of pique or slug so
those correlate to different fields in
the model so PK is also known as the ID
field so ID actually equals to pk but it
stands for primary key it's a little bit
more advanced but if we try to look up
by slug let's just change the URL to
being slug the keyword argument URL slug
it's saying that it can't resolve this
into our field well these are our only
options active Content ID and title so
let's go ahead and go back to ID and
then override something in our view this
is the def get object method this is
built in to class-based views especially
with detailed views list views it
doesn't make sense right because a
detail view wants one thing we're all
this view wants a list a query set so
let's go ahead and get this
by using a method we have seen before so
get object or 404 so all we're gonna do
here is return get object or 404 the
actual model name itself and then we
want the ID well how do I actually get
the ID from the URL like how do I get
this keyword argument from the URL it is
quite a bit different than the view for
it right the view for that detailed view
it's passed into that general function
but on our class-based views it doesn't
work that way so instead how it works is
we can use self dot keyword args that
get ID so this is the actual keyword
arguments that are being passed through
that URL you can see what they are by
printing them out but this is how we
would actually override what that
keyword argument is to our URL and then
we can look at our view and what do you
know it comes back and it works just
fine
so it's very similar to what we've seen
before but it's just slightly different
now I understand that this probably
feels a little bit more confusing than
this but the main thing here to
understand is class-based views inherit
from a lot of different pieces and to
override its primary function is just
get object detail view the primary
function of a detailed view is to render
a template from a specific object now if
I got rid of this query set here and
refreshed it would still work I actually
don't need that query set what the query
set does is it limits the choices
available for that detail view in other
words let's take a look at that if I
change this to being like filter ID is
greater than one don't worry if you
don't understand what that is but if the
ID is greater than one and I changed my
URL back to that primary key again
that's the default we're overriding that
default crew set now if i refresh in
here it gives me a page not found and
that's because the default query object
is not in
side of this query set it does not exist
in there so that's something that's
really cool too and probably hopes that
hopefully this makes you want to learn
more about query sets but anyway I'm
gonna go ahead and leave that comment it
out leave that object in and leave the
URL back as an ID because this is almost
identical to what we've already done
with our other views
to have a create or update view we want
to make sure we have a model form so
this model for I'm going to go ahead and
import into my views
so from forms import model form and then
I'm going to go ahead and create my view
so I'm actually gonna well I mean can I
copy this can it be the same well it can
be definitely very similar so we'll call
it article create view and there we go
and I'm gonna call this create write so
I need to make that template article
create HTML and much like product
creates it can just render out a form
very simple so we got our view here
let's go ahead and bring this in to my
URLs and again create as view open up
that path and let's go into blog create
okay so we're missing something here
it's saying using model for mixin
without the fields is prohibited well if
we look at our view we see that we
actually didn't bring in our model form
so what if I just did form class equals
to article model form say that refresh
there's our form if I ran through this
it would actually save that data it
would work by default and it's going off
of all the validations if any inside of
my model form again those validations
the ones that we did in product model
form so if I wanted to validate the
title I would say clean title those
sorts of validations and also the
built-in ones as well so this view does
that for us and it's that we still have
that same query set and we also have a
method called form valid takes in self
and form so what we would say here is
this is actually the form valid data so
I can actually do print form that
cleaned data
and then I'll just return super the
superclass the built-in the default of
form valid of that form but this will
allow me to see what data is actually
coming through here so if i refresh new
title this is my second post I hit save
I do get this error this is critical we
will adjust this but if I look at my
terminal before that error I can scroll
up and I see that clean data okay so
what is this error get absolute URL that
is a method that should be done by
default inside of your model so if we
look back in our list those items are
stood there like it actually did create
that item except didn't go anywhere so
if we create this get absolute URL
method get absolute URL and well I want
it to be based off of reverse like this
one so if I copied my other one I would
just do something along these lines here
I know I'm sure cutting things but you
should know how to do this already okay
and then the app name is articles for
our reverse and it's gonna be article
detail okay so the reverse function is
to go to that detail view so now let's
go ahead and create another post and say
new one this is a new post we hit save
now it actually takes me to that URL so
then is a critical method for the get
absolute URL method and part of the
Creed view it's actually also part of
the update view as well but the main
thing here is I can also change where I
want that to go by just overriding the
success URL like this or define get
success URL and you can return some path
that is another way to override that but
but the default method works really well
for us because chances are good after
you create an article you're probably
gonna want to look at it so
the actual next part of this is pretty
simple we can copy this create method
I'm gonna put it underneath my detail
view and change it to my update view so
article update view and much like our
detail view I'm going to be updating a
specific article so I can just use that
get object method again and well pretty
much get rid of everything else I don't
actually have to change the template I
can bring this now into my URLs and grab
this change like that so if I wanted to
go update it I would just type out
update oops not updated but update and
we might need to make sure that we save
everything okay go to update and this is
my third post I hit save it brings me
back to that method so deep the create
and update are almost identical the only
difference is it actually grabs an
object or an instance of the thing it's
trying to change still using the same
form still using the same query set
moving objects we just used the delete
view and it's very similar to the
detailed view so article deletes view
and delete view and then we're going to
use a different template called delete
and then again we still want that get
object method here and my actual delete
form is identical to the one that we
created in product with the exception
that I called it product here and post
here so we save that we save our views
here do some imports and bring in a view
name as view uncomment this out same
stuff so let's go back into a post let's
say for instance post two and delete it
do you want to delete this we say yes
again we don't have a success URL here
and in this case it wouldn't use the get
absolute URL method because well that
object no longer exists as soon as I say
yes it deletes it from the database so
this is not even seen because that
object is gone so what we need to do is
set one and instead of setting the
actual string so like success URL to
something like blog what I'm gonna do
instead is I'm going to bring in my
reverse call so from Django URLs import
reverse actually let's put that right
under here and then I'll just go ahead
and say define get success URL takes in
itself and it's gonna return reverse
blog list view or you know whatever we
have here which is actually article list
good thing I looked so we change it to
article list and this is also articles
okay right there
cool so now this is our new delete view
I can't leave that query set but again
it doesn't matter just like the detail
view because of my get object call there
and I saved that and now I go to delete
do I want to delete it we say yes it
deletes it it brings me back to all my
posts very simple and something to note
is that air
the delete error if I don't have that
get absolute URL method or rather get
success URL method and I try to delete
something and say yes that error
actually prevents that deletion unlike
the creation just something interesting
to know but that's class-based views
that's that's the gist of it
here is a fairly standard function based
view and all it really does is render
out a template that we already have and
granted I made a new app for this
I made some URLs and I added it into my
settings as well as my URLs so make sure
you know how to do that but I have this
function based view and if I look at it
this is all it is it just renders out a
template not a huge thing going on here
you have to convert this into a
class-based view we're gonna inherit
from a class called view so this is the
base view class so base view class
equals to few and all I'm going to do is
say class and whatever view I want to
call this in this case I'm gonna call it
course view and again we're gonna pass
in that view there so to have the exact
same function work I can bring it right
over so that function based view I'm now
turning it over here but if you remember
our actual name for our function based
views don't really matter but inside of
a class based view they do matter and
they're correlated to the HTTP method
that it's trying to handle in other
words get is the default so get will run
here but like if you were submitting a
forum like fo RM you would often use the
post method and that's actually how
you'd handle a forum we'll get to that
later but for now we've got our course
view we'll import this into our URLs we
will render that out comment out our old
one our function based view here save
that and refresh in here and we had a
little issue we have to actually add in
self here as well because if you are
familiar with Python when we say
something like a new obj or a new object
of a class you often do something like
that and that object is an instance of
that class sort of reference something
like get we have to actually reference
self inside of there and with that we
should solve that error so if you see
something like this that means you did
that same
I just did which is rather important to
see and now it's actually rendering out
that template just fine with that
standard get method and you can print
out the various methods if you'd like is
request method but notice that these are
identical with the exception of the fact
that this is in a class so one other
benefit of doing this is saying
something like template name equals to
about HTML and then we would just go
ahead and say self dot template name and
that renders out roughly the exact same
thing so this is pretty cool the other
aspect of this is literally coming in
here and changing this template name to
contact dot HTML save that refresh in
here what do you know my template has
actually changed so that's one of the
huge advantages of using class-based
views is how easy it is to change things
so we now have this model in here and
I'm gonna bring it into my view to have
this being a detailed view how do I
actually handle that now to do it we
want to pass in a parameter from our URL
so inside of your URL stop PI inside the
amp
we are just basing off of our products
URLs not any different they're nothing
new so I want to actually make both of
these templates be able to work so to do
this I'm gonna pass in ID equals to none
ID equals to none means that the ID is
no longer required when you do it with
just ID that means that argument is
required saying that it's none means
that we have a default here you could
also set another default if you like but
basically that means that these two
template or these two class-based views
will actually render just fine now let's
actually take a look at this and what
I'm gonna do with my standard template
is I'm gonna do courses slash detail or
rather course detail to you know go
along with the detail view generic view
so I'm gonna go ahead and make my folder
for that templates new folder and their
courses new folder or a new file in
there saying course detail but HTML and
I'm gonna go ahead and just copy and
paste something I've already done before
and just use the title because that's
the only field I actually have in my
model okay so I now have the class base
view running twice but two different
template names one is contact out HTML
the other one is well going off of the
default of what I set right here so let
me go ahead and save that and let's go
ahead and run it out instead of courses
if i refresh in here contact is still
showing up if i go to one or some sort
of detail I have an empty template now
why do I have an empty template is
because I haven't passed any context
into this template itself so to pass
that context and we'll just do from top
models import course
and we'll go ahead and do get the
shortcut get object or 404 and I'll just
say object or a rather obj get object or
four or four course ID equals to ID okay
and since I have a default being none
I'll say if ID is not none meaning if
the past argument is not none then I'll
go ahead and say this is what the obj is
and I'll also set my context up here so
then I can just augment it here with
object equal to obj and there we go
or rather we want to pass contacts to so
we say that refreshing mayor says hello
world that is the name of my first
object which I could also add in just
the ID to just double-check that I'm
doing everything correctly save that and
there we go we've got our ID and hello
world
let's go ahead and create the raw
ListView
very simple course list view and
inherits from view we can add in a
template name here much like we've done
before and I'll just call this course
list and then I'm gonna do something new
and that is setting a query set here so
course not objects at all and then I'll
just go ahead and do to find get self
request args and keyword args and then
we're just going to go ahead and return
well
the render of the request the self dot
template name and then my context I'll
just put in a dictionary here and say
object list equals to self dot query set
for better illustration purposes I'll
just leave it in as that context just
like that okay pretty cool so I bring
this into my URLs and now I'm gonna go
ahead and you know get rid of this other
one and leave that in as view here and
then in my templates I'll go ahead and
say course list dot HTML and from my
product list I'll just copy that one
there and I'll not worry about a link
for now I'll just show the actual title
save it okay and go back into our
courses just that one list and we see
that I've got two in there very simple
very easy but I want to go one step
further to get it closer to how the
generic view works and that is defining
the get query set method here and what
it's gonna do is well it's gonna return
self dot query set and then in my
context instead of query set itself it
will just will call self dot get queries
that or this instance method here
instead so if I say that a refresh in
here it's the exact same however if I
actually inherited from this and said
class my list view from that course list
so let's just put it right underneath
here and I said query set and I put it
equal to course not objects not filter
ID equals to 1 this will actually give
me a list of items even though it will
only give me one and I brought bring
this into my URLs and use that one
instead save that refresh in here let
sure make sure I have saved everything
ok
i refresh in here what do you know there
is the biggest benefit of using
class-based views is this inheritance
property of course I'm not actually
going to end up doing that but I wanted
to show you four Illustrated
illustration purposes
when you create something you want to
accept two methods that's the get method
and the post method so I'm going to go
ahead and grab the course view here
paste it over and call it course create
view and we have our get method in here
I'm gonna leave it in as empty context
and then we want to have our post method
because when you actually create
something you post it to the back end so
we want to make sure that we have post
really simple I don't actually need the
ID argument passed through here we're
not using that and of course the
template itself is going to be course
create now I want to bring in my form
which is from forms import and the name
of it is course model form and I want to
actually initialize this in two places
right one is the get method will say
form equals to the course model form
make sure that it's empty just like that
and then inside of my context I'll have
the form of being passed because my
create template has that need okay so we
say this let's bring it in to our URLs
and add it in as a path
okay really simple stuff so far let's go
ahead and go into that and we see a
title here okay so if I type some stuff
out and hit save it doesn't seem like
anything happens well nothing actually
does happen because our view actually
accepts post data but it doesn't do
anything with it so what we have to do
is come in here and grab the request
post whatever that data is so again send
context we bring it in here just like
that okay so this will allow me to
actually have the form data coming
through with whatever that context is so
let's go ahead and create something and
it save seems like things have happened
let's go back into my courses I still
don't have anything in there because of
course I still need to come in here and
say if form is valid then I would just
do form not safe and that would give me
the actual method to save a model form
now I want to test this method to make
sure that something like this actually
renders out and to do that I use
something called field validation so in
a form we can actually have validation
with clean underscore whatever the field
name is so the field name
I'm validating is title but it could be
any of the model fields or any other
form field that you might use in case
you forgot about that so we're gonna go
ahead and come in here and actually do
it so title is equal to self dot cleaned
data dot git and then the field name of
course and we'll say if title lower is
equal to something like ABC then we'll
just should go ahead and raise forms dot
validation error and this is not a valid
title okay so this is only on the form
level right it doesn't do it on the
model it only does it on the form that's
a key distinction here that you should
remember obviously we're not going to
touch it just yet but that's the key
distinction so now that we've got that I
didn't change anything in my view let's
go ahead and try it out coming back in
here I just type out ABC hit save I see
that it says this is not a valid title
so in other words what our post method
is doing is it's actually coming through
and initializing what needs to happen
now there is one other thing that you
might consider doing and that is once
it's valid you might actually want to
re-render the form so I say another
title I hit save it stays in there
although I might want to create another
form or another course or whatever it is
that I'm building right so I want it to
be empty I want it to be in its original
state so to do that all I need to do is
reinitialize the actual form itself
though our update view combines the
things that we just did create and also
detail so we've got this update view
here and we have two methods that are
gonna be there for sure
and they're the same basically all
they're doing right now is rendering out
the form so it's really not a whole lot
different than the create view as it
currently stands but the thing that I
want to actually adjust is this get
object method so this method itself is
going to override what you would
typically do for your detail view you
would have a method in there called get
objects so then you can use it in your
various methods otherwise right so like
as we've done here that is actually how
we're gonna call that object so what I
want to do then is just pretty much grab
the same data that I've done before
which is this right here this get object
or 404 related stuff right here right so
this is gonna grab that detail and to
grab the ID we just do self that keyword
args that get ID those are obviously the
keyword arguments that are coming
through on our URL like we see here
and ours right now is an integer with
the name of ID and this will actually
grab that object for us so I'm just
going to go ahead and say obj equals to
none and this will grab that object so
now we have some object inside of our
context so this will work on both our
get method as well as our post method it
will have that object in there and if we
look at our template it's a combination
of that detail view and that create view
form and now what we'll do then is
actually update this item so we have
this item here all I need to do is pass
it in to my form as an instance so
instance being obj and I want to have
that also down here in addition to the
request dot post so this is grabbing
that post data along with that instance
this is initializing that looking to see
if it's valid and if it is then it will
save everything for me and then finally
my template has the method of post and
the form really hasn't changed so let's
go back in here and let's take a look
I've got my update view here nope we got
context error so we want to make sure
that we have context defined and that's
this right here that should not actually
not be there a little mistake sorry
about that okay so we come back in here
a hello world I'll just change it to
being hello I'll hit save it changes it
to hello I go back to the detail view
it's still hello if I go back to the
update view and change it to ABC and it
save it does that validation again now
you can probably see that this is
redundant code and it is and that's
because of how we had to do it by raw
detail we started doing stuff that's not
redundant code but really at this point
it's like you might as well use that
generic class face view that built-in
classmates views that we've already gone
over right so I mean this is just so
much cleaner and simple but the idea
here is really understood this is the
raw version of it
continuing off the idea of the update
view we have this delete view it's
pretty much identical except we don't
need to bring in the form and then the
final thing that we would do is actually
have a redirect so we actually delete
the object on that post method and then
redirect it somewhere after importing
the redirect and of course my URLs I
update that and then in side of my
templates themselves the form that's in
there I just rendered out this raw form
as we've seen so we want to do delete
the course instead and the idea here is
that we render out this sort of confirm
message and then post that message
saying yeah we confirm once you do that
post message then you actually delete
that item so let's go back in and take a
look at our courses I'm gonna go into
course three delete and there we go so
we do want to delete the course another
title we say yes it deletes it redirects
really really simple but this is the raw
way to do it
mix-ins are part of the reason that
classmates views are so good what a
mixin does is it allows us to extend a
class-based view with some new code
let's take a look so what I'm gonna say
is class and we'll call this course
object mix in and it takes in just
object as is default object is just a
Python object and then we're gonna go
ahead and say that we'll give it model
name or model class or just simply model
it'll give it to being none and they
will do a method called get object and
then we'll return something related to
what we've seen before and in fact we
will return this right here so we've got
our object here and instead of course
we'll just do self dot model and of
course the default itself is going to be
course so we'll just leave in that
default so this is now going off of this
right the next thing is let's go ahead
and just say URL lookup or you know
lookup simply and this is going to be
equal to ID so now that I'm here I can
just change this to being self dot
lookup okay so that's pretty much it
this will help me reduce redundancy
inside of my code so I can grab this
object mix in and just bring it into my
delete and quite literally get rid of
that get object method now because it
actually works in here it's this right
here is going to call the mix-ins
version and you want to make sure that
you put the mix end first and then the
classic view or the final class last and
then we can do the same thing for update
we can do the same thing for create or
well actually we don't need it and
creates but we also don't need it in
list and then finally detail alright so
the object down here instead of being
all of this we would just do context
object equals to cell type get object
because the rest of it is going to
handle as we expect right so it's going
to raise that error if it's not there
just like that and it's gonna look up by
that field on for
the lookup is gonna have to be identical
to what we've got here right so this
this makes things a little bit more
challenging doing the lookup like that
so I'm gonna leave it back in as I D but
the general idea here is that we would
in theory be able to change what the
lookup would be but in my case I'm just
gonna leave it in again as ID but that's
how this is actually works the mix-ins
actually work just like this so now that
I've got all that let's go ahead and
take a look inside of courses it's go to
the first one
still working update still working
delete still working
so we've now reduced the amount of code
that we have by creating our own mixin
and of course as you see we can make it
more complex and once you make it more
complex then our class reviews are even
that much more super-powered
[Music]