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

And we're back >> And we are back

Welcome back I'm Christopher Harrison That's Susan Ibach This is Building Websites with Python and Django, and I'm going to be slightly unprofessional here Barry, do you want to reset the timer for me, please? >> No

>> Otherwise, I'm just going to talk on and on and on, and all those poor people who it's already 6:00 pm will be there until 4:00 am You guys want us to have that timer

You do >> Yeah, yes Much happier Thank you, Barry Okay, in any event, just in case Barry decides he later wants to clip that out, this is Building Websites with Python and Django

That's Susan Ibach I'm Christopher Harrison So there's been a lot of questions in the discussion about can you compare Django to fill in the blank? So can you compare it to PHP? Can you compare it to Ruby? Can you compare it to MVC? Can you compare it to a lot of other different platforms? >> ASPNET >> ASP

NET And here's the thing, is at the end of the day, all of these are different tools, and they all have different strengths and different weaknesses So, for example, when it comes to let's take for example Django versus MVC, and I'm going to focus in on two real quick things on each of them First of all, let's talk a little bit about forms, that one very cool thing that Django offers is the ability to actually create a class that's going to represent an HTML form, and so all I have to do is essentially create a placeholder, say, hey, use that class, and Django will automatically create the HTML for that form, which can be very powerful >> But on the flipside of that, if you're one of those people who's very picky about the way you want your form to appear, you may not like the way the default form gets created I actually saw a couple of comments of people saying they found getting the form to look exactly the way they wanted to was they found a little frustrating with Django >> Absolutely, absolutely, and so that's it

And so with MVC, I don't get that automation In MVC, at least out of the box, and I know that >> When you're saying MVC, do you mean ASP

NET MVC? >> Yes, ASPNET MVC And I know that there's going to be somebody in the forum that's going to say, well, wait a minute, with MVC, I can write code that would do this and automatically generate a form and so forth, and you're absolutely right And I've actually written a lot of that code myself But here's the thing, is that's something that's not out of the box

That's built right in with Django, and so that is one of those advantages, that it's very easy for me to do that in Django With MVC, it does require that I go in and start creating that little bit of a framework on my own So it's kind of a which do you like? Do you like that level of control, or do you just want to use what's out of the box? Or to go with one other thing, with routing, MVC uses what's known as attribute routing >> Again, I can say ASPNET MVC, just because we've been just talking about MVC in Django, so I just want to make sure we're really clear there

>> Yes, ASPNET MVC So the thing about ASPNET MVC is it uses attribute-based routing, which means that I go to the controller, and then I decorate the controller and I decorate the different actions inside the controller with different attributes, and so all of my routing is actually handled on the controller Meanwhile, with Django, it's all done by using regular expressions, and it's all done inside of the little urls

py file Of course, you can create multiple, but it's done inside of there So it's sort of a different approach, and so which do you like? Do you like it on the controller, or do you like it all centralized? And so Django is going to give you that all centralized, with MVC, it's going to be done on the controller Now, one last little thing, and then I'm going to let you take the rest of the module, Susan, is once again, with MVC, I know that you can also do your routing centralized, as well, but the preferred mechanism now with MVC is to do that inside the controller So all of that's a very long kind of rambling way of saying that each one of these will have its own strengths, its own weaknesses, its own little quirks and a lot of times, it will come down to a matter of personal preference, and sometimes, it will just come down to a matter of, you know what? And let's go back to the forms thing

I know that Django can create forms I just need something up right now Django is going to be perfect for that, because it will automatically create the forms I don't care about formatting Go

And so you can just do it with Django, for example So it really just comes down to a matter of personal preference, and each one of them has its own advantages and disadvantages You want to talk about ORM, don't you? You just want to talk >> No, I said I'm going to have the easiest MVA ever What I'm going to say is, to sum up, it comes back to the answer you can put to every single question that ever comes back to the Q&A

It depends >> Yes, it depends >> Unfortunately, that is the answer It really depends what you're trying to do, so the strengths of Python Django, it can create forms for you very quickly with a preset layout So that, some people like that, some people aren't happy with the preset layout, so they might prefer something else, but that's one of its advantages, that for quickly building a website that is going to give you forms, to show you and access a database, that's one of Django's advantages

>> Yes >> All right, now, I think it's time to get to a file, new project >> Yeah, let's do it >> We've covered a lot of high-level stuff Let's actually dig into writing some code from scratch

So what I'm going to do is I'm actually going to start talking about that back end of we keep saying Django is good at talking to a database Let's start seeing how that works and how the code works to do that

So what I'm going to talk about in this module is I'm going to just sort of talk about the concept of a model Christopher, you talked in that first module about model view controller We're going to focus in on that first part, the model in the model view controller And how does that connect to the database itself? Because the model is in our code, how does that work with the database? And then we'll actually see how you literally write the code to create your model and then how you connect that model to the physical database on the back end, so that's what we're going to cover here, and we're going to do that very much from scratch and start building that record store setup that we were talking about So I had a couple of suggestions that it should be a hockey app for the next one, just so you know, Christopher

We should do that one during hockey season, though, at this point >> There you go >> Right now, it should be soccer or football, I think, based on >> Women's World Cup >> Women's World Cup is on >> Go USA >> Go Canada All right, so when we talk about code and we talk about a model, what exactly is a model? Well, when we talk about model view controller, I'm just going to bring that slide back up, that diagram we had, it was a model represents our data

The view is how the user is going to see that data, and the controller is what's handling the user's requests, so when a request comes in to add something new to the database and then to return results back to the user to display something, that's the controller In the end, this is all code It's just how we're separating it We think of the model code, the view code and the controller code So, again, using that diagram we saw earlier, a request comes in from a user

It gets sent to the controller, where there's some code that says, oh, look at that request coming in, how do I handle that? And that controller might say, oh, they've asked for information about a particular artist, so at that point, the controller goes off and goes to the model and says, hey, I need data about this particular artist, and then that data needs to be put into a view to decide, well, how do we show that information to the user, and then that actually gets sent back to the user as a webpage that they'll actually be able to see containing the data that they requested So the model, again, that's our data, and the data you want to see depends entirely on the entire sort of application you are building, so it could be customer information It could be product information It could be information about hockey players or soccer or football players It could be reservations for a restaurant, so that's the data that we're really working with inside our application

And in code, the model is a class So if you've done any object-oriented coding, and if you haven't, this is something you're going to want to just go read up a little bit on basics of classes, properties and methods and inheritance those are sort of the basic concepts you'll need to be able to work with models inside Python

For us, a model is a class So, basically, for every table we would have in the database, we're going to end up with one class in our Python code So in our case, we're going to deal with some artists, different musical artists and keeping track of the albums we have, so I would probably in my database end up with an artist table and an album table, so I'm going to create a class for artist and a class for album Now, just creating a class doesn't magically connect it to a database There has to be something we can do that changes it from a class to really being a model that represents our data, so there's a few rules we have to follow when we create our classes in Python, if we plan to use them to represent our data

So let me show you a couple of those rules Because in the end our web app is going to be a front end for a database That's probably why we've chosen Django As I said, customer management system, reservation system, trivia application Now, a lot of times, traditionally, if you took our Flask course, we actually showed you who to write SQL statements to connect and talk to the database

And that, if you already know how to write SQL statements, it's something very natural, but if you are somebody who started off in code and not with databases, having to learn all that SQL isn't always that natural for you You may be very comfortable working with object-oriented code The other problem is, then you also have to worry about what we call SQL injection attacks That's where you have a field where somebody can type in the artist name and they type artist name equals, and then a name, and then they add and select also the system administrator's name from the system and the server name, please, so that comes back on the returns, or and create a super-user account while you're in there >> Obviously, that's not the exact SQL that they'd type in

>> Not quite, no I'm not going to tell you how to hack my system So we do have to worry about those SQL injection attacks, as well So if we don't use SQL commands, then we're protected from SQL injection when we use this sort of abstraction And the other thing is, SQL can be specific to different database products

The specific SQL used to connect to Oracle for joins, for example, could be a different query syntax than it would be if you're writing it against SQL Server, so there is some slight differences, even though it's a standard SQL All the database products have a few little quirks and some specific ones So the other advantage to not writing straight SQL statements is if you ever change database products, it's going to be less rework for you So that's where this idea of object relational mapping comes in So the objects are the classes that we create inside our code

And the object relational mapping, which we call ORM, or sometimes called the object relational mapper, depending on whether you think it is doing an action or it's a thing, it's basically a layer between our code and the database And this is something Django gives to us This is one of the things people like about Django It's one of its advantages, if you like this approach to code And what the ORM does is it converts our queries, which we just write as code in objects by doing like method calls and so on, so we call a method, and the ORM takes that method call and says, oh, I'll write the SQL for you, and then it gets the results back and puts the results back nice and tidily right back into our classes for us, whereas if I was doing this in something like Python with the Flask framework, I would be writing a SQL statement to say, go to the database, get this result, take the results, put them into the properties represented by the class, so I would do that manually

The ORM is going to do that for me So if you imagine I have an artist class, which I've created in my code, and I call a method that sends a query and basically tells the ORM, hey, I want to go get a list of all the albums by a particular artist, the ORM converts that into an SQL statement, which then gets sent to the database The database executes that query, sends back the results and the data, and you can sort of see that in the diagram there, so the results come back from the database, and then that's used to populate artist object on the other end So the ORM is the magic in the middle that's going to save me work So the bonus of this is it's going to simplify creating your application, so you can focus on just writing and creating your classes and not worry so much about the lines of code that connect to and query the database

And it also means it is easier to handle a different database down the road without a lot of rewrite What you'll discover is this isn't something unique to Python and Django There's other implementations which are ORM, as well, the Entity Framework A lot of people asked about ASPNET, and ASP

NET MVC Well, you can use Entity Framework or LINQ in ASPNET Those are examples of ORMs that you can use in ASPNET

You've got hibernate, which works with Java, and we've got this one here built into Django, so this isn't a concept unique to Django, but it's the most popular implementation of it in Python So how do we actually do it? It's one of those ones at some point we want to start playing Well, we want to create tables We have reached table and database We're going to need one class

And I did say earlier there would be some rules that make those classes map to databases properly One of them is that each object is actually going to have methods that interact with the database There's going to be a save method for each class The save method is what we will call when we need to do an insert or an update insert a new record or to update an existing record of the database And delete, for well >> Wait, hold on, delete >> For delete, exactly So there's a delete method we use if we want to delete a record And we have queries, which we can use in lots of different types of queries We're actually going to cover queries in a totally separate module, just because there's so much on querying

Now, to create the class the good news, here's the awesome start Remember, we said Django does some stuff for you

You don't have to write the save method You don't have to write the delete method You don't have to write the query methods All that code is written for you Sweet

I am a lazy programmer If you've watched some of my other MVAs I've ever done, I am all about being lazy and getting the tool and the system and the framework to do the work for me So the fact that I don't have to write the code for the insert, update, delete and queries, two thumbs up from me, I'm a happy camper Now, how is this possible, you may ask >> How is this possible? >> Great question, Christopher, I'm so glad you asked

>> Thank you >> Glad you caught your cue there >> See, I am paying attention >> I know I can see you're busy answering things in the Q&A window It's always tough when we're trying to do Q&A live, so do forgive us if we can't answer every question as it comes up, but the way we do that is we have to inherit code that's already written

So if you take a look at the slide here, you can see that when I create the artist class, it inherits from the model class inside the models package So that model class inside the models package has the logic for save, delete and the queries Now, the queries are generally done through something called the objects collection, so whenever we want to do queries, we have this extra property that automatically gets added to our class, because we inherit models, and that is the property we'll use for creating data If you're a little confused, don't panic We're actually going to do examples of this in the next module, so it will make a little more sense when we actually do it

Now, of course, if you have database tables, well, you would usually have columns in that database table, so if I have an artist table or an albums table, I might have the title of the album I might have the year that the album came out I might have a picture of the album cover for the artist I might have what year was the band formed and otherwise, so these become properties of our class So for every column we have in the database table, we're going to end up with one property for our class

And if you think about a database table, you'd probably end up needing to specify the data type of that column Is it integer or is it string or is it date? You'd need to specify the size of that column Can it hold a really big numeric value or a smaller numeric value? Can it handle decimal places? For characters, usually, you have to specify the maximum number of characters you can store in that column? And nullability Is that column allowed to have a null value in it, yes or no? So when you create a table, you have to specify those values Well, if we're going to create a class that corresponds to a table, we're going to have to specify the same things

And the syntax for doing that, basically, if we take a look is you give your property name, and the property name is basically going to be your column name, and then you actually say the word models, so the word models never changes, because we're using the models package here, and then type and type is actually going to change depending on the data type of the column or the parameter, property we're specifying And then we can specify different parameters This is going to affect other properties of how the column is treated, like whether it's nullable or not, what size is it and so on? So the data type is going to be controlled by that type, and the parameters are going to determine things like what size is that field and is it allowed to hold null values So let's take a look at a couple of specific examples

So if we take a look here, we actually have a column name here called name, so this is actually going to be the name of the column that would be created in the database, and remember, I said this word models here, this doesn't change It's always models, because we're saying, oh, it's going to be a character field, because a name is going to hold strings, and then we have different parameters we can specify, so we might specify the maximum length, so it can be up to 50 characters long, 80 characters long, 100 We can specify whether or not it's allowed to hold null values, whether or not it's allowed to hold length values and a default value if there's none provided for that column Sometimes, you might have a field such as salary, which defaults to zero, so these are all examples of parameters you can specify for this field you're going to have

Now, that's for a string field What if you need a numeric field? Well, if you take a look at that line of code, name = modelsCharField(parameters), the only thing that changes when you create an integer field is this little word here, IntegerField So instead of CharField, we now say

IntegerField, because we're basically telling the models package, hey, this column I'm creating, and it's funny actually now that I realize it's called name, I should have obviously updated that slide So that integer field, basically just saying this column or this field is a numeric data type, not a string data type But you still have parameters you can specify, such as does it allow null values? You can have default values You won't bother specifying a size, because that's determined whether you pick integer field or positive integer field and so on So let's do it

I think it's time to go, and I feel the need to go into Visual Studio and do some coding, because it comes a point, I get twitchy if I haven't been in there for too long So I'm going to go file, brand-new project I like Christopher's point, there comes a point when you just need to see from scratch I select Python I'm picking Django web project and database fun

All right And I'm going to go ahead and click okay, and once again, we get this option Christopher was talking about this earlier about I wanted to install into Python I like using the virtual environments, because that gives me more control in case I end up working with elements of my package that may need to work in different versions of Python, so I'm going to leave it at 34 is the version of Python we're working with

I'm going to say go ahead and create that, and then I get to play the what can I do to pass the time while waiting for this? So what I'm going to be doing is, when this is done, I'm actually going to go ahead and start creating classes in the code that are going to represent the database tables, and we're going to have an artists and we're going to have albums, because we're working on this record store example And what I'll need to do is I'll need to create those classes

And, of course, there's model, view and controller And because I'm working in the models, I'm going to go when I open up the Solution Explorer, I'm going to be adding this to the models code

So I'm going to create albums I'm going to create artists, and then I need to think about what would the columns in the database be, and for each column, I'm going to have to go ahead and create a property And still spinning, and it's a beautiful day in the neighborhood, isn't it? Oh, here we go, we're off >> There you go >> I was going to burst into song

It's amazing I don't think even Visual Studio wants to hear me sing Now, if you look at my screen right now, just want to reinforce that it pops up with this thing going, before running this project, you need to synchronize the database >> Don't do it >> No, that's right

Don't do it We're going to show you how to synchronize the database I'm going to show you actually that in this module What I want to do, though, is I want to start creating my code So let's go over here, and underneath the Solution Explorer, under templates, if you go take a little look over there, you will see there we have models, so it's under app, under templates

We're going to go to models, because remember, we are working with a model So we're going to add our code to that modelspy file So I open up that file, and you'll notice the first thing, hopefully, that you notice is that it imports, right away, the models package That's the one that contains the model class we need to make sure all the classes we inherit have the functionality needed for the ORM to correspond to the database So now we can go here, and we can add a little code >> I love the fact that it just tells you, create your models here

Well, thank you >> Yeah, it's very helpful I like that So we're going to create a class called Artist, and this is basically now, the magic happens when we add this little bit of the code, where we say this class is going to inherit from the model class in the models package That's essentially That's what makes the magic happen That's what gives it the built-in methods that allow it to communicate to the database

And then I say, well, in my database, I would have a name column, so let's add a name property, and how do I declare that? It always starts the same way, models, and now I have to say what data type is it going to be Well, this is going to be a character field, so I'm choosing CharField, and then I pass in different parameters to specify what's its maximum length, does it allow null values and so on? And I'm going to specify a max length here of 50, and then maybe I want to ask what was the year formed, and that's modelsPositiveIntegerField I would never have a negative year, so I might say a PositiveIntegerField, and actually, I don't really need any parameters

The default is going to be fine for those, and then maybe I need to create another one for album >> And while you're typing that in the background, we can leave Susan's screen up while she types away here, there's been a couple of questions in the Q&A about people that created the project, tried to launch it and it's failing, saying it can't find the database The reason is that we haven't actually created the database, and this was something we kind of mentioned earlier, is that we're not going to be creating the database or even showing the UI until a little bit later So we are going to get in, we're going to create the database and all that, but we haven't gotten there So if you try to launch it right now, there's no database

Django wants that database right up front, and so it's going to fail So if you're trying to launch the project now, like if Susan tried it don't do it

But if Susan tried it, it would actually wind up failing at this point >> Yeah I can save it I can build it, but you're right, I cannot launch it yet >> Yet

>> But it will >> Yes, it will >> It will So I now have two classes, one for artist, one for albums, so that's like having two database tables, and in the artist table, if you want to think of it that way, it's got a name and a year formed, because I have fields for both of those, and I have name field or property on the album class, so I'm defining what effectively is sort of what my database would look like, but I'm doing it with my model Okay, that's it

I bet you thought that was going to be way more complicated code Well, there's some more magic coming One of the things that comes up all the time when you work with databases is the need for primary key Certainly best practice for a table to have a primary key A lot of times, the primary key is an ID, album ID, artist ID, employee ID, customer ID

And it's usually an auto-generated number Every time you add new customer, it just increases the ID number by one Django actually does that for you If you don't specify an ID property, because I didn't specify an album ID or an artist ID, it will actually generate an ID column for me and just automatically increment the numbers when I add new records Awesome

That is just sweet Now, on the other hand, if you're like, no, I don't want it to work that way, it's okay You can customize it if you want, as well Let's say you have a string, a character field you want to use as a primary key Then all you do is when you actually go ahead and create your field, all you do is specify that

you specify a parameter, primary key equals true, and now that name field is going to be treated as a primary key You can do it with integer fields, as well That's fine, if you don't want to use that sort of auto number

Or let's say you want to create a field, and you don't want it to be called ID, so you have a special column you want to use as your ID, and you do want it to do that automatic numbering for you, where it just automatically increments by one when it adds new records, you can do that, as well You just specify auto-field, and what that does is it creates an automatically incrementing numeric field, and you say, hey, and that also happens to be a great primary key for me So you've got a lot of choices there for me I'm going to be as lazy as possible I told you, I'm a lazy coder

I'm just going to let Django generate ID fields for me, automatically increment numbers for me, saving me time But there might be situations where you don't have a choice, so you do have control when you need it Okay, now, the other thing that comes up when you work with database is the idea of relationships, artists and albums Well, artists record albums Each album is recorded by an artist

So a lot of times in database tables, we need to keep track of those relationships, so we have the ability to say, give me all the albums by that artist, or go tell me information about the artist who recorded this album Even though they're stored separately when I'm presenting information through my views to the users, I want to be able to show the related data So we have that concept of foreign keys that connect the two tables, and Django also allows us to create foreign keys, and I love the syntax for this This makes so much sense to me So what I do is I create my new column, so there's nothing new there

I create this artist column or artist field, and the first part should look exactly the same You say it's in models, but here's where it changes I say, by the way, this is going to be a foreign key, and it's a foreign key that points to the artist class Now, I don't have to tell it which column to point to or anything I'm simply saying, hey, you know what? I want to be able to track the artist for this album, and that artist is going to be the artist object, and it's actually going

Django will take care of mapping that to the ID field or whatever you defined as the primary key in the artist field You don't have to do that You simply say, hey, guess what

There's a foreign key here Album has a column called artist that points to the artist type Done Again This is where Django rocks

It's taking care of it for you So I guess I should add that incredibly complex code >> Yes, absolutely >> All right, I like to do all the tough demos up front here They'll blow up later on

So all I do is I go to my album and I add a new column, and this one's going to be called the artist, and it's modelsforeignkey, so this is going to be a foreign key, and basically, it points to the artist class Done I now have a foreign key connecting albums and artists together, one line of code >> And it's one of those things that I love about that, is that I don't have to remember what the ID is, and the ID could potentially change

All I have to do is just suddenly say, hey, there's the parent, and it takes care of it for me >> Yes Honestly, it's the way it should work I wish it worked that way in most databases >> Look at that table, figure it out

>> Yeah, come on, there's only one primary key You make me point to the primary key anyway, so it's nice, it saves me work As I said, I'm a lazy coder Make Susan happy Now, one of the things you may have noticed, and if you've done other MVAs or watched any other MVAs with Christopher and I is that something very interesting here, if we go back to the code briefly, notice how year formed up here, we specified or I specified an underscore between year and formed

It's very unusual We tend these days to sort of go year and then uppercase F Formed The underscores are getting more unusual to use in variable names That is not an accident That is not there just because I like using underscores

That has functionality Christopher mentioned earlier that Django can actually create forms for you based on that model When you use that underscore, what happens is when it auto-generates the forms, that's going to control the labels that are automatically generated So year formed will become year space formed, so the underscores indicate that when you generate the label for this to put a space between those two words, and I believe it puts the uppercase on the second word >> On the first word

>> On the first word, so it will also do some uppercase automatically So yes, we do want underscores when you have sort of multiple words That controls the labels that appear afterwards So that's something, it's not an accident It is deliberate

If you want to customize the label, you don't like that, you don't want the name of your property necessarily to be the same as what the label that appears on auto-generated forms will be, you can actually specify a parameter, just like we can specify size and whether it's nullable There's a parameter called verbose_name which allows you to give it custom names So I can go back to my code here, and what I'll just do is I'm just going to add verbose actually, it's by default it's actually the first field So I can literally just specify that for the name of the artist, instead of it showing name on the screen, I want them to know it's the artist name, and I can show album instead of name for the album name, because I think that's going to look better when we actually display a form to show artist and then the name of the artist, album, and then name of the album, as opposed to two fields with the label name on them That might be confusing to the user So that's the verbose name property, another nice little thing you might want to set up Because if I set it up there, it saves me work later, and so I'm willing to put a little extra work in now if it allows me to be lazy later

Finally, I need to get these, so basically, that was my little demo of getting the model ready for display, controlling the labels that are going to get generated Now, there's a whole bunch I've only just touched the tip of the iceberg in terms of the types of parameters you can affect that will change things, how you can handle more complex data types, custom column names and so on So there's a link here, and you do have the ability to download these slides, where you can go see all the different parameters you can specify when you create the fields that will control the way those fields are created So lots of options there for you to play with

So we have classes, but I'm sure everybody's still sort of going, how do these classes actually end up as a database? >> Yeah, there's been a couple of questions actually around the database >> Yeah, everybody's going, keep going, Susan, because I don't see the light's not coming on

You're like, that's just too easy >> Yeah, what about the database? >> All right, so let's get on with the database Okay, first of all, first question, what database is Django going to use? Huh, right Good, excellent question, and the answer is, whatever database you tell it to in the settingspy file

So if I go over right now over to my Visual Studio and I go find the oh, where is the settingspy file? I can never remember

Do you remember where it is? >> What are you looking for? >> Settingspy >> Oh, under database fun >> Oh yeah, under here Thank you

Under database fun There you go, settingspy And if I take a look here, one of the choices you will see if you dig down, there it is Under databases, you can see it's specifying right now that it's going to use SQLite

Now, I'm going to use that as a default, but you can go and change these to point to whatever database product, if you already have something installed and you want to use that database You can specify your username, your password, host import, everything here, to connect to SQL Server I saw somebody wanted to do Postgres You're just going to have to find the connection string required to connect to that type of database That's the magic of Django, remember? We can just change the settings here to point to different databases

And I know I'm going to start in SQLite, but you're going to change this later, aren't you, Christopher? >> Yes, I am, but much later >> Yes, much later, so we will prove that point We'll make that happen live All right, so we're going to be using SQLite inside my demonstration here, but it certainly works with MySQL, with SQL Server and other databases, as well It's just the default development database for Django, and it's a nice, light one when you're learning and trying things out

It's just a lightweight relational database It is also open source, so nice place to get started when you're getting into databases How do we actually create it, though? Because right now, nobody's run a create database command or a create table command or anything What we do is we do something called migration, so the way Django ORM, the object relational mapper, works is you say I've defined the structure of my database by creating this class, and now I'm going to say, migrate that structure to an actual physical database So we do this with something called migrations

So there's basically two big steps you have to do The first here is the command makemigrations What that command is going to do for me is it's going to say, create a brand-new package based on the code we have in our models, read those classes, read those properties I defined, and based on that, create a package that contains all the changes to send to the database Once it's created that package, there's a neat little thing you can do if you know SQL, and it might help you sort of wrap your head around how ORM works There's another neat command here you can try, and I'll show it to you, called sqlmigrate, and that'll actually do is it'll actually show you the SQL statements that got generated when you created the migration package

So if you have done SQL, doing that might help you understand what's going on behind the scenes If you've never done SQL before, you just want to trust Django to do its magic, you never have to run that command Then, the next command, this is the magic one, the second magic one, is migrate That's the one that actually says, okay, do it You created the package

You read my classes You figured out what the tables should look like based on looking at my classes and the properties that I defined You created a little package that would create them When you run the migrate command, you're saying, actually take that package, run it against the database which database? The one I specified in my settingspy file, and create the physical database At that point, you have literally created a database that maps to the models you defined in your code If later on you discovered you missed a field or you need to add some additional fields or additional classes, you go back to your model, you add the classes, you change the properties, you add properties, you rerun that makemigrations command, create a new package

You rerun the migratepacket command to update the database with those structural changes Obviously, though, keep in mind there are some changes you might make that might require blowing away all the old data and recreating tables from scratch So that is something you can't just say, I've decided to get rid of this table altogether, or delete, rename four columns You may lose your data in the database when you try and migrate those types of changes, because I don't know, the database doesn't usually like it when you just rename columns on the fly and change database names and things like that So there are some migrations that can cause you to have to lose your data to be able to apply the changes

So I guess people so how do we do it? We start with the make migrations command The command, in terms of what do I have to worry about, some of this is going to be absolutely fixed, so we call python manage

py makemigrations All of that is standard code That is going to be the same no matter who here is running that code What we need to control is the name we give to the migration You can leave a default name, if you want, but you can give it a name

I'm going to call mine initial, because it's the initial migration creating my database table, but everything else on that slide, everything else you see in that command, is exactly the same no matter who's typing it, so all you have to do is decide, what do you want to call your migration? And that's going to read the code in your modelspy file and create a migration package Once you've done that, how do we execute it? In Visual Studio, we're actually going to do it from the command line, so I'll show you how to bring up the command line tools inside Visual Studio, so you can execute these commands, because Visual Studio uses an older syntax, so this is the way that's going to work if you're inside Visual Studio If you end up using a different tool, you may have different ways that you execute those commands, so let's see how it works So I've got

I'm going to just show those models again, because I want you thinking more about the models and settings, so there's my classes I created, and there's the properties, which I defined Now, I go to my project, and I right-click on the project name, and I choose open command prompt here, so that's what I'm going and picking the open command prompt here Do that again, and that's going to open up command window for me, and if we think, what was the command we saw earlier, it was python manage

py, because I'm running the managepy code is running this for me, and I'm executing the make a migration package, so makemigrations, which will create a package based on my models, so based on these classes I had created over here

And I have to give that migration a name I'm going to call it initial, and I tell it the name of the application I want to create a package for My package or my application is called app, and that will be your default application name inside Visual Studio If I'm lucky, I typed it correctly Woohoo, score one point for no typos there, and you can see here that it's gone ahead and created a new migration, and this is actually the name of my migration 0001_initial

That's important to remember, because later when I want to migrate that package to the database, I may want to be able to tell it exactly which migration to move You also can see, it said I found an album and I found artist, so I can see that it's read my models file and found those objects So the next step, I just want to run a couple of commands to show you a couple of neat things One of the things you can do is you can say go to python I'm just going to resize this window a bit so that's a little easier to read

Not quite Okay, so python and managepy You always start any of the commands in this command window when we're working with migrations always start with python managepy to specify where the code's running, and I can say, show me the migrations I've created for my app so far

And that will simply give you a list of all the migrations you've created, because over time, you could imagine, as you're making changes, you might have multiple migrations over time So that just gives you a list of the migrations you have, and for those of you who do know SQL, personally, in my head, everything makes more sense for me, because I'm really a SQL person, when I do the SQL migrate command, and I say go look for my app a that package 0001_initial, and show me the actual SQL commands you're going to run when I run this command or when this package is executed to the database And this will actually come back and shows you the actual create table command, so now I can actually see, oh, look at that It's saying create table called app_album, and it's going to have an ID column But we didn't specify an ID column

There's that magic of Django, saying, oh, you didn't specify an ID column By default, I'm going to create one for you It will be the primary key It will auto-increment And here's my name column, which is a varchar 50, which makes sense, because I had specified in my model that it was going to be a character field, right? And it was going to be a character field, so that came in as a varchar, and I said max length of 50, so sure enough, it made it a varchar 50

I didn't specify if it was nullable or not The default is, it's not allowed to be nulled So you can start seeing how what you specified in your field maps to the SQL statement that's going to be executed against the database Once you've looked at that and you're comfortable with it, and you go, you know, that is actually what I wanted I'm cool with the auto-incrementing IDs that it's generated for me

If I wanted to make changes, I could go change the classes, rerun the makemigrations to create a brand-new package, but I'm happy with this one, so at this point, I'm ready to say let's do it Let's put that code, run those commands against a database so I have a table that maps to this So I run python managepy, that never changes And you have two ways of doing the migration

If you really only have the one package, you can just say, migrate, and it will basically apply all current migrations to all current applications, and I only have one app and one migration, so it'll basically run it, or you can actually say for my app app, I want to run the migration 0001_initial So it's your choice You can just say, hey, just run the current migrations, or you can say for this app, apply this migration And when you run that, hang on Let's run

I'm going to do it the other way for now Because it's the first one, it tends to be happier if you do it the first way with a straight migration Python manage

py migrate, and off it goes and says, all right And if you take a look at the messages and things popping up there, it says, yes, I'm creating your tables I'm installing the custom SQL, and basically, it's just created the tables inside the database Do you want to add something there, Christopher? >> Oh, no I was going to say the other thing that it's doing is to manage the migrations, it actually has a table that it uses inside the database to track all that, and so it was just going in and also setting that up, as well, when you called that initial migrate, so that just needs to be done first before you can call those individual migrations

That's all >> Yeah, but once you've called that command, migratesql, I don't need to now run the migrate app 0001_initial, because when it set up the initial tables, it also found that migration and applied it, as well But now, any additional migrations I do, I would simply say, only here's the new migration, run this command or when it's 0002_initial or whatever package names I give it, every time now I make additional changes to my classes, I would just rerun I would do the make-migrations, so I would run this command to create a new package to reflect the changes I've made to my classes, and then I would rerun this command, except I would have to change the migration package name to be the new migration package

And that would migrate changes I made to the class to the database for me All right And that takes us to the end of another module We now have the ability to create classes, which define a structure or database tables, create a package that we can then run on the database to create tables that map to those classes >> Beautiful

So now, I guess the next thing would be to actually put data into there and pull it back out >> Yes, that's the next piece in line >> What do you say we take 10 minutes and we'll come back and do that >> All right See you soon

>> All right, cheers