Developing Websites from Scratch using Python and Django -Part 3 (HD)

[Music] Welcome back to Building Websites with Python and Django I'm Christopher Harrison

>> Your coffee's right there >> That's Susan Ibach My coffee is right here In any event, in the last modules Susan you showed us some really neat tools for being able to create classes that's going to be our data Then use that to create the database

But how about the actual you know data? How do we actually work with the data without having to write the SQL manually? >> Yeah, absolutely That's definitely the next the step All we've done so far is we've defined some models Remember models are just classes we created in our Python code Then we used the ORM or the Object Relational Mapper to migrate that model to the database itself

Basically what we now have is classes inside our code and tables in our database But there's no data in these tables One of the things we promise is that Django would also help you with writing your queries, doing your insert and updates statements That's what we're going to try and demystify now Is how do you actually start working with the models in terms of code, inserting new records, updating new records, and so on

What I'm going to cover in this particular module I'm going to show you how to create new records, how to update records Then we'll get into some queries We'll look at some very simple queries like how do you get back a record where ID equals Then we'll get into more customized queries

We are only going to scratch the surface here When you get into custom queries I use to teach SQL courses as well There was a three day course on writing SQL statements to do things like queries and so on We could probably do a full one day course on writing Python queries through the ORM in Django, showing you all the different options and features We'll get you going with it so, but you can write some basic queries

Hopefully get use to the syntax so that when you want to do something more advanced you can very quickly find that syntax and see how it applies We're going to get you up and running Get you to like the 200 level But you can go to 300/400 level We're just going to scratch the surface because I know you guys want to see things like the bootstrap, how to create the forms, how to migrate/deploy this whole thing

We want to make sure we get a chance to show that as well Let's start with creating data I want to, yes, Christopher you pointed out >> Makes sense >> I've got no data in my tables, so I want to start adding some new artists, adding some new albums into there

Let's do that Now, the great thing is if you now have ever done object oriented coding If you know how to create an instance of a class, you know how to create a record Because basically, remember, our class is our table When you create a new instance of the class, that's creating a new record in the database table, and the ORM is going to take care of taking that instance of the class and sending it to the database

Now it's not just going to do that randomly and go you created an instance I'll just move that to the database for you You control when it sends that new record to the database, like calling a method When you call the save method that's your way of saying, hey, I've got a new instance here Please send that new record to the database

Or if you modify a record you say, I've made a change I want to send that change to the database Calling the save method is your way of saying now is when I want to actually send that new record to the database How does that look in terms of code? Well, if we take a look here what we end up with is I have my Artist class that I'd created I just say, alright, let's create a new instance of the Artist class

I just call the construction method I say, alright, the value for the name is going to be Artist Name, whatever I type in The value of the year_formed is going to be whatever year was formed Then when I want to send that record to the database so it actually inserts it into the table, I just call the save method Now, some of you may be looking at that going, Susan, you never wrote a safe method

It's true, if we actually look at the code there's nothing in here There's no save method >> Susan, you never wrote a save method >> I never, you're right, I'm glad you brought that up, Christopher But remember when I created the Artist class I inherited from the model class

That model class in the models package has the save method, so that's where that save method comes from I don't have to declare it here I inherited that from the model class Now to test this to sort of show you how it works The easiest thing to do is actually you would writing this code inside your web pages, and sort of the logic of your code

But I'm actually just going to open up a command window where I can just run some Python commands So we can do it interactively so that we don't get lost in the navigating the structure of all the pages right now We can focus in on literally how do we write that code that's going to interact the database, insert our record, query our records? The way we do that is in Visual Studio if you want to try this yourself You go to your project You right click the project

You pick Python, open Django shell This basically gives you a shell where you can execute to Python, Django commands It's popping up here Let's bring that up here so it's going to be a little bit easier to work with There we go

Here's my shell I can go ahead and say, I want to create a newArtist It's going to be an instance of the Artist object It is case sensitive so got to be a little careful there As an Artist object and I'm going to go with my favorite band

I'm a big fan of Great Big Sea Christopher's laughing because he knows I'm inclined to burst into song at any moment with songs by that band Let's say they were formed in say 1985, somewhere around there I run this command and basically, oops Oh, you know what I forgot to do? >> You forgot to import an artist

>> Right, this is a blank shell It doesn't know what the artist model is I just have to go to my application, whoops, import from the appmodels because remember this is in the modelspi file of my app, so it's an app

models I want to import Artist That's why it's going hey, I've never heard of Artist Once I've imported that then I can go ahead and create my newArtist Okay, so I've successfully created an artist

But right now that's just an instance of the object in my code I need a way of saying take that instance object That is meant to represent a recommended database Go do an insert statement of the database based on that What I do now is I call newArtist

save That's that method I inherited from the model class It is now gone off and inserted that record in the database We'll see that in a little bit when we learn queries because we'll actually do queries to get that record back That's how, that's it

I mean look at all the incredibly long, complex code I wrote over here again Over on the left hand side you can see here's this incredibly complex code I used to define the data, the model, and all the columns in the database when I migrated Here's the incredibly complex code I wrote to create a record and insert it to the database I said this is one of the reasons Django is so popular is because its, if you're use to working with objects this is very intuitive You don't have to go off and learn all the SQL, ORUM does it for you

Let's pop back over to here for a second If you want to do an update statement, so we need to update an existing record What you can do is once you have an instance of the object that represents that record Change its property because each property maps to a call in the database If you change one of the properties, in this case if we take a look here

You can sort of see we've got the name property of our artist We change it to some new value When you want to send that updated value to the database, send an update statement to the database Once again, you're just going to call the save method If we try that and put that into practice, we just go over here

We go newArtistyear_formed and we say, let's say for that particular, because I have this instance newArtist already I could just modify that record and say; year formed is 1986 instead of 1985 Then I just say save and the ORM is going to detect what's been modified on the newArtist instant, and send an update to the database with that change, done I've just done an insert and an update

>> We don't have to worry at all about the database itself It's just taken care of everything for us >> Yeah, the save statement is basically telling the ORM hey, take any changes, any new records, any updates to that record, send them off to a database >> I like it >> Yeah, great for the lazy coders, happy Susan

Alright, so I've just done that demo Now of course I know there's a lot of people going out there, you say it's saved, Susan But I'm not sure I trust you You know they've probably seen me do demos before No they don't always go perfectly, so alright, fair enough

This is where I'm crossing my fingers really hoping it did work So that the next command demo works because if the first demo didn't work I'm going to find out right now This is my moment of truth I'm now going to run a query to go to the database and say hey, give me back that artist that I just inserted How do I do queries? >> How do you do queries? >> Well, we use the save method to send update and insert statements to the database

The way we do queries is that model that we inherited in our code Again, coming back to the code itself, here's moving this out of the way Once again, right, all the magic happens because we inherited this model class We inherited the save method from that We also inherited an extra property called objects

The objects property is a collection of the records that are in the database effectively When we want to do a query we always work with the objects property It has its own methods that allow us to do queries We're going to go to Artistobjects

filter, objects, Artistobjectsget, Artistobjects

filter That's always going to be sort of our logic when we want to say go get this record from the objects for Artist Go find these records from the objects of Artist It's all about that objects property which was added automatically because we inherited from the model class In terms of a code how does it actually look? It's going to look something kind of like this

If you take a look here what you see is here's that Artistobjects That's the magic here I said that was added automatically because we inherited from model This time I'm calling the all method which, okay Christopher, I'm going to put you on the spot for a second

Take a wild guess at what the all method will do? >> I'm going to say it's going to get you everything It's going to get you all the items, download all the things >> There you go, download all the things, exactly When we call the all method basically it's going to go off and would tell us all of the records stored in the database for the Artistobject

Then we put that into some sort of collection object like allArtists Then if you want to see the results of that you could write a little for loop that says, just go through all, each artist inside allArtists Then print out whatever property you're interested for in this case, maybe the name If you only want to get a single record back, well you can do that as well Because again, we always start with that Artist

objects, right That's our property that allows us to access the records We call the get method and we ask it for one Now, one of the things what that is sort of doing is that's kind of if you've done SQL It's kind of like saying select where ID=1

That's kind of what we're doing when we do a get statement You know because we specified a value of one by default that one is going to be the ID If you just specify, I'm just showing you how to do it like where name= in a second But that's with default Basically that's equivalent of sort of saying select where ID=1

Once you've got that record back you can display it Let's try that out because again, I think this is one it makes more sense when you see it in action We've inserted a record to the database We should be able to say get me back all records The way we do that is I say I'm going to declare a variable called allArtists to hold the results of the query back

I have to go to the Artistobjects method I love IntelliSense It saves me making some typos I'm going to start by doing the get me all objects back

That, basically that method has now just executed The ORM has taken that command, gone to the database said, hey, somebody asked for all the artist objects It's gone to the database table, done a select * from this table, gotten the records back, and populated my allArtists variable with every single record form the database In this case only one but if you have 50 records it would populate it with 50 Now, how do I prove that? Let's go back to our code

I'm going to write a little for loop here Well, actually I can do it this way It's a collection so I could just say get me the first record Go to the first record and tell me what the ID is If I run that it says the ID is one

If I say from the first record, oops, get me the name It says Great Big Sea You can see it in fact did bring back that first record Or if you want to see all the records, in this case there is only one But again, you could still do the for artist in allArtists

Don't forget your colon I always have trouble with that in Python I always forget my colon when I'm writing for loops I could say and then for each artist that you find print out that artist name It comes back again; in this case I only actually have one record, so there's only one that returns

But if I went off and created a second artist and saved that it would retrieve all of them Now, what if I only want to retrieve only one record back and I, because of course if you really only want one record back It's really very effective, efficient to say go bring me back 6,000 records and then retrieve the one you want once it's all brought across the network to your code If you know which record you want back, you know its ID is you can say, go get me the record with ID of 1 Let's try that out in the code, see how that turns out

For that I just say individual Artist = and we always start with Artistobjects But instead of doing the all we say just get the record 1 When you say get 1, it assumes you want to get the record with the ID equals the value you pass in here

That's basically a one, whoops, actually I'm going to do it this way, id=1, even simpler There we go, id=1 Then we can ask for the Artistname of the record It comes back and says the record with an ID of 1 is Great Big Sea

I can ask for one individual record or I can just get all the records back and loop through them and process them There are basically select statements that I'm running against the database The ORM is doing all the magic for me I did not write a get method I did not write a save method

I did not write a query method I'm just using the built in functionality of Django and ORM Let' do some more magic There's got to be more we can do with this because that's you know what I know as soon as you start to get into queries You guy start going what if I want to, well what if I want this type of query? Oh, wait I want it to be case insensitive

I know the Q&A window is going to light up as we start getting into queries here We can't cover them all But there's a lot of great documentation on it But I will get into some slightly more advanced queries here We used the get method

Now the thing about the get method is the get method is kind of like if you've ever done select statement in code There's often a command called select into The way it works is it's only allowed to get back one individual record If it returns more than one record you actually get an error message You'll actually raise exceptions

If it returns no records you'll get an exception back Anytime you use the get method to retrieve a record from a database If you get back zero records it's going to throw an exception Something along the lines of no record found I don't remember the exact exception it throws

If you retrieve more than one record it returns an exception Something along the lines of multiple records found If you're executing a query and you don't know if it's going to return zero records or 15 records, you know if it's just saying where ID equals If that's your primary key you should only get one record back But if you're saying get me all the albums by the artist Great Big Sea

You might get back 15 results In that case we need a way of saying get me multiple records We have that all which gets us everything But what if I only want the records by Great Big Sea; I don't want a list of every single album in the albums table

I want only the records by Great Big Sea At that point I'm doing sort of a where clause I'm trying to filter out the results But I'm still going to get back multiple results I'm going to get back ten records

That requires using the filter method If you go back to the slide for a second, you'll see here there's another method we can use, called filter That's the one we used to bring back the multiple objects Important to know when to use each and if you're using get make sure you do your try, except I'm channeling my inner Christopher here by scribbling all over the screen

Make sure you do a try, except to handle the exceptions of no record found and multiple records if you do use the get >> You are going to notice we're not going to bother with try, except just to try and keep things a little bit simpler I mean best practice yes, put it in We're not going to worry too much about our handling side >> No, not because we're just trying to show you how it works

>> Exactly >> Okay, so let's take a look at the syntax of how we use it If you want to not search by ID but maybe you want to find the record where name equals something It's actually very similar syntax to what we did when we were searching by ID Once again we start with Artist

objects That's a constant That's the same anytime you do a query We are expecting maybe I'm saying get me information about the artist named Great Big Sea I expect that to only return one record

Because I expect it to return only one record I can use the get method Then instead of saying ID=, I just simply say get me the record, where the name = whatever the artist name is That will work just fine You could be your name =, what year formed =, whatever column you want to specify If the other one, now this is where it starts getting cool

You could also do things like you may have used In SQL world you may have used something like, let's do this here You may have tried something like select, where, like, something great% Maybe you've tried these sort of like statements These idea of pattern matching in your were clauses

You want to find things that start with the phrase Great but you don't know what it ends You know great gobs of fire, Great Big Sea >> Great gobs of fire

>> Great expectations and so on What we can do is there's the ability when you use the filter This of course could return multiple records I'm using filter this time instead of the get Again, always start with Artist

objects I'm using filter because it could return more than one record But instead of just saying name =, I say name_startswith = Great That startswith is a clue It's a parameter I can specify when I call the filter method to say any name that starts with this phrase is a match

That's like saying get me the records where the name is like Great% and so on, if you've played with SQL statements It allows me to do pattern matching in my search I do want to point something really, really impointant in this slide, impointant, important in this slide >> Important >> That is, whoop, two underscores hang on, that was nice

>> Yes, two underscores >> That is two underscores That's name__startswith It's not always clear when you're looking at a slide But that is actually underscore, underscore there if it has been typed in

Now the other thing that you run into is our search is case sensitive That comes up a lot of times in databases In Canada our Postal codes or zip codes We call them Postal codes in Canada they have letters in them You run into a lot problems where when people are on a webpage they might enter the Postal code in lowercase

But we, when we're searching for it sometimes we search for it We don't know whether to search for uppercase or lowercase letters so that causes problems Sometimes we want to be able to do a search and I don't care if you entered a lowercase k or an uppercase K, as long as it matched the letters I don't care if it's upper or lowercase Any of these little tricks that you see, or these parameters you can specify

You have the option to specifying a letter I on the parameter It turns it into a case insensitive search If you take a look at the slide here you can actually see that I do the startswith I, first parts always the same Artistobjects

I'm using the filter because I could get back multiple records I'm doing the name__startswith, with two underscores But you'll also see that little letter i there That turns this into a case insensitive search If I entered Great Big Sea with lowercase letters this would return a match whereas the previous one would not

There's other ways to do this too What if you weren't doing an exact match? You're not doing this pattern matching Well you could do that as well We have another great example here If you take a look at, again it always starts the same; hopefully this is starting to look familiar

Starts with Artistobject and if you're going a get you're expecting to get back one individual record Or only get me the record; you can do this with filter or with get You've got the get and you say name = Artist Name You're like well how do I make that into a case insensitive search? You can do it because you can; these two commands are actually exactly the same

The only difference is here I say name__exact instead of name = The advantage to using this name__exact syntax is the fact that I can add an i if I want to right here That turns it into a case insensitive search There's actually an example of that on the next slide You can see here that I can just add that i to turn this into a case insensitive search as well

Lots of options here Let's go try a couple of different queries here for some examples, to sort of show you some more complex queries inside our code that we have here What we'll do is first let's do a sort of get me the record Instead of searching by ID let's search for the record where name = instead of where ID =, because that comes up a lot in your code You never know exactly which column you're going to be searching by

I might say searching it by name, the name of the artist is Artist, oops, objects That's always going to be the same I'm only expecting one record back with the name Great Big Sea

I can use the get and get me the record where name= Great Big Sea How do I know it worked? Well I can just print out the result and just say what's the value of nameArtistname? Sure enough it comes back with that or if I wanted their ID value Or I wanted to know the year they were formed, year_formed, any property I want You can see that whole record came back, oops, name

Artistyear_formed Oh, nameArtist that would do it, the field is called nameArtistyear_formed

Must be getting close to a meal time I'm starting to seem to make more typos in my code As we all know of a number of typos you make is directly proportional to the number of people watching your type >> Exactly >> The more of you watching >> Everybody close their browser window, no I'm kidding Stay, I'm kidding >> Yeah, alright Okay, so what if I want to retrieve multiple records back? Let's try that filter which allows us to retrieve multiple records

I might say execute, get a list of queryArtists and we always start with Artist I seem to have this obsession with an uppercase R, must be because my talk like a pirate tendency is in going ARRR Artistobjectsfilter and when we do the filter we say, get me all the records where a year_formed=1986

If there were ten bands from that year this would still execute successfully It won't throw any exceptions because the filter remember can handle, return multiple records To get the results back you could write a nice little loop and queryArtists Then each time through the loop just say print the name of each artist That again, in this case I only have one record on the table, so only seeing one result back

But if there were ten bands this would list off all the bands who had the year formed 1986 That's kind of like saying select * from artists where year_formed=1986, if you think in terms of SQL, if you've worked with SQL already If you've never worked with SQL you don't have to learn it because ORMs doing it for you You just need to learn how to call these different properties or set these different parameters to control the data you want back Another one I want to mention because it may come up

Is you may be going what if I want the records where year_formed=, and country of origin=? How do I do like an and statement or something like that? To combine the way you do that is just to sort of show you the logic Is after the filter you just add another filter statement I would add country=Canada

You can do that as well You can even say there's another way of, I won't execute this because I don't have a column with country=Canada Another one you can do is kind of cool is there's also the ability to say except as well I think it's except, it's something like that >> Exclude

>> Exclude thank you because yes except is usually an exception You can say, exclude country=Canada If I want to know all the bands that were not from Canada that were formed in 1986 Then you can add another filter afterwards This is how you combine all kinds of different conditions together

You just keep adding more exclude, filter, filter That's how you have multiple conditions on a query if you want to

Just wanted to mention that because it's something that sometimes comes up Trying to think of some other neat ones, let's, oh, we got the foreign keys I think we should show that Yeah, alright, one more thing I want to show you This is cool

>> Because you haven't had an error yet >> Well, no I had one >> Oh, okay, alright >> Typo, there's one more thing that's really cool that I absolutely love about this as Susan the lazy coder When I taught a lot of SQL statements and select statements and we work with relational databases

The data is often spread across multiple tables The artist information is in the artist table The album information is in the albums table If I want a list of album names, all the albums by a particular artist Then what you would have to do is you would have to query both the tables and join that data back together using what we would call SQL join statements

Trying to explain to somebody who's never done SQL before how you write these join statements that combine the data from table A with the table from table B, and bring that all back together That was, took pretty much I would say, you use to teach SQL, Christopher I mean that was a good solid hour wasn't it really? >> Oh, yeah >> Even after the hour people are kind of like I think I get it It's one of those concepts that frequently throws people off

ORM does it for you >> You don't have to worry about You don't have to worry about trying to write that, yeah >> You don't have, you're not going to have to write join statements Because remember how when we created the artist and albums we made that foreign key between artist and album

You remember we did that? Django already knows that the, which artist go with which albums All we have to do is say, we call it like a, people think of it like a parent/child relationship You know each artist has multiple albums We might think of artists as the parent and albums as the child You can literally say, go get all the children for, by just saying you know follow that relationship

Just go get me those records This is really cool The way we do that inside Django is you basically can walk this relationship chain, walk your foreign keys By following that relationship we created As long as you made a foreign key between the two objects you can just go ahead

Again you look at the syntax and you wouldn't even know you're doing a foreign key search here You still go ahead You still call Albumobjects You know you may get multiple records back so you're doing filter rather than get

Then I just say get me the record where artist__name is, and you specify and Artist Name But here's what's interesting about that Is artist__name is not stored under albums If we actually go and look at the class we created here There is no artist__name here

We have the album name But we don't have the artist name We said however there would be an artist That for artist there is a name field Basically when you look at the syntax here what you're really seeing here is this is saying the field artist

Then again this is two underscores on that artist; look at that artist's name property Get me the record where the artist's name property is, artist__name Again, very careful that's got to be two underscores or it's not going to work Let's try that out because I think that's really one of the coolest things about Django Is this is, this comes up all the time in your code

You have all the orders for a customer, all the albums for an artist You have all the items that somebody ordered that you have to track together This sort of idea of get me all the orders for a customer, that sort of parent/child, foreign key comes up all the time You have the ability to just say hey, just go get them All you do is in syntax say I just need the artist__name= and it finds it through the foreign key, it's great

To do it I'm going to have to import the albums here because we haven't actually added the album class to this little window we're working in here, inside our shell We better import albums so it knows how to use the album class Right now I don't actually have any album records I'm going to insert a couple of new records to the album database I've got to flashback now and remember how to do my inserts

To do that I create a new instance of the album class and I'm going to be a little shortcut on my code here I could just, I could say, newAlbum = Album I can do this and then I can call newAlbumsave But I'm going to do a little shortcut here

I'm just going to go straight to the constructor of the Album class I'm going to say create a record where name= up That's one of the albums The artist is newArtist because we do have a variable, an instance already called new Artist which points to Great Big Sea That saves me having to set all that up already

Then >> The only reason newArtist works is because you had created that already, yeah >> That's right, yeah, it would be great

If we go way back up here, remember We created an instance of an object >> A long time ago >> Called newArtist with the name Great Big Sea I'm just taking [Indiscernible] a because otherwise I would have to write a query to go get the record of the artist I wanted it to point to

Then use that here I'm just taking advantage of the fact that I already have an instance of an object that points to Great Big Sea I specify newArtist Then I can just say as soon as you create the instance save it to the database I made a mistake somewhere

Artist=newArtistsave, name= >> Oh, yeah you were supposed to get an error there >> Not yet, it shouldn't blow up until I'm just trying to insert That shouldn't blow up just yet

Artistsave, album, name= up, artist=newArtist, and I think that's correct and save I've just got to make sure I have the casing alright on that It is newArtist, yeah that's correct There we go, here's my blow up of the day

Couldn't get this far without something blowing up, I'm going to take a quick look at the error message; app_album has no column named artist_id >> Can we run a migration just in case? >> Sure we can do that That's going to require going over here Alright, so this is the live debugging with the Python Django MVA Let's go here

It shouldn't make any difference though Python, do you want to rerun the migration or? >> Yeah, so just say manage py >> Managepy >> Just say

>> We do the make migration first or we might as well, eh >> Just try migrate, just try migrate >> Try just doing a migrate alright we'll try that

Migrate, synchronizing, no migrations to apply Your models have changes that are not reflected in the migrations that have been applied >> Oh, okay, yeah so you will need to rerate a migration >> Yeah, I'm going to rerate the migration just to make sure that the database reflects the structure I think I have, so yeah let's do that, python managepy makemigrations -name pleasework app, okay

I'm trying to add a non-nullable field artist to an album without a default You can't do that The database needs something to populate existing rows This is interesting >> Just provide a one of value

Just hit one >> Yes, set a default Obviously I should have specified a default value when I defined that column Alright, so now let's do the migration >> Yep and then, work

Actually you use provider value yes >> Let's redo the make migrations >> This is your [Indiscernible] value >> Enter the default now as value of the date time, time zone now It's a date time

Why do I have a date time field? I didn't think I had any date time field Excuse me, a little confused here Positive integer fields, charfields, ID field >> Just give it a value, just type in a number one >> Okay, we'll try that _ there we go

Alright, so it's adding the field artist to album which it did need You know its funny somebody brought up in the Q&A that they didn't notice the foreign key to artist in the SQL statement Maybe you spotted that there, good eye I didn't, I wasn't looking for that I was just looking at the create table statements

Now let's do our python managepy migrate to migrate those changes, okay >> There we go, now >> Alright, now let's go here and see if it will successfully let me create that new album, yay, thank you Christopher >> Okay, you're welcome

>> You have earned your cookie for the day It's like we can't >> We'll figure something out

>> It's all good You have earned your cookie, sir >> Alright, yeah >> Alright, so now we can go add a second album Not because that's very odd that it didn't create it on the first time

Now we create a second album Sea of no cares The artist is that same Artistsave Okay, so now we've created two albums by that artist Now we should be able to do one of those foreign key queries where we say go get me all the albums where the artist name is Great Big Sea

The most important thing to realize, right, is nowhere in the albums class is there an artist name field It's this foreign key that's going to allow me search by artist name, even though artist name is in Artists and I'm querying Albums That's the kind of neat thing That's where the magic of Django comes in I can go ahead and now I should be able to say, okay, list of albums =

Always starts the same going to the objects property, doing a filter, as opposed to a get because I'm expecting multiple records back Get me the record where in the artist__ the name property, so I'm pointing to the name property of the artist class I'm going to the artist of album But I'm asking for the name property of the artist = Great Big Sea Now, this, the good news is I was expecting this one, big nasty error messages all over the place

You know sometimes those pop up and you're like, ah, Susan, it bombed on you But there's times when we're like, now this will be different >> Yeah, this one we expected Though I like Danny's immediate instinct was oh it blew up Let's not show that on the screen like that

>> I loved that that was great Yes, I do have to thank Danny here at the studio for very kindly the moment the error message was spewing all over my screen, going I better save her by going back to video because sometimes we don't expect these messages But actually we can bring this one back up This big nasty thing is basically just popping up Sometimes there's certain setups when, especially when you're working in the shell parts of a Django setup that aren't completely loaded

That allows the foreign keys to work There's just an extra little command I have to run I'm going to have to just import Django Import django and run djangosetup

That's going to just setup the components that aren't in this Django shell that allow the foreign key to work Once I've done that Now this time if I get big nasty error messages, Danny that'll be your cue to show Christopher, right away, smiling away, if there's an error message in my [Indiscernible] this time But we're good, okay so we run it, nice, it goes to a prompt It's apparently executed successfully

How do I know it worked? Well, I check the results I can say, okay, for each album in the albums that I just got back Let's print the albumname I should see listed all the albums

There's up and Sea of no cares the two albums for that artist >> Beautiful >> That's effectively a join statement in Django with one line of code >> That's it >> Happy land for lazy coders is what it comes down to

I believe that sort of takes us through to the end of another module We've done some pretty powerful queries >> Sort of does I actually want to kind of go back and do a spin on the demo that you just did >> Oh, sure

>> Here's what happened, is Susan just walked you through how to actually create and then query back data by utilizing the Django ORM APIs which is wonderful and that was the exactly goal Then somebody in the chat window said, hey, how about, and you can actually cut to my screen here I've got it up, how about using the DB Browser for SQLite and showing us the database? >> Oh, sure >> I went hey that's a great idea Let's go ahead and do that

I went ahead in the background here and I created that same exact very complex structure that you created I've now opened up the database What you'll notice here is that I've got my app_album and app_artist, those are the two tables in question here You'll notice that if I go to app-album and I hit refresh that right now I have no data If I go to Visual Studio here and let me do the exact same thing

A lot of people have been asking how do we get to that Django shell Again, it's right click on the project, go to Python, and then open Django shell There we go Now what I can do and I'm just going to shortcut this I'm just going to say Artist and I'm going to say name = The Cure showing our music tastes here

We'll say year_formed = and I think it was 1978 There we go Then we'll go ahead and call save >> You're also showing your age >> There's that too

>> Oh, you haven't imported You forgot to import artist >> Oh, you're right, thank you from app import Artist >> Appmodels I think they have to specify

>> Yeah, you're right, appmodels, there we go Thank you, there we go I'm trying to kind of move a little quick there >> Yep, yep, no I understand

>> Yeah and so now you'll notice that I've saved that Now if I come back over here to my database sure enough there's the data You will notice that it is in fact updating the database behind the scenes By the way this DB Browser for SQLite is a very simple little tool to use If you just fire up Bing, do a search for DB Browser you'll find it

Then you'll notice that you can just hit open database and then navigate to the directory that that happens to be in Then obviously you'll notice that you can go in and just refresh Then that will show you all of the data right there There it is actually being saved behind the scenes Susan showed off everything that your typically going to have to do when you're using Django

>> From a code perspective >> Yeah from a code perspective What I love about all the demos that you did was the fact that you didn't actually do anything directly with the database You didn't care >> Because I don't have to

>> Yeah, you didn't care where the database was, what the database was But just to kind of prove that yes it is in fact saving inside the app >> Yeah, sometimes you're sitting going I think it's populating a database behind the scenes Or sometimes you're running a query and you can't get a match You're like is that because a record doesn't exist or because I'm running my query wrong? It's nice to sometimes be able to look at the original table and look at the records

Go, no, the records there so now I know it's my query that's giving me trouble That absolutely is very helpful, great suggestion and thank you to whoever made that suggestion >> Very cool, yeah, I can't remember who it was, but gold star for the day In any event I don't know about you I don't know about everybody that's watching

But I'm hungry We're going to make this all about me Let's go ahead and take a meal break We'll be back in about an hour >> See you soon