Python for Entrepreneurs Transcripts
Chapter: User accounts and identity
Lecture: Demo: Account object creation
0:02 So we have our account table, now let's go insert some data into it.
0:05 Let me run the app and remind you guys how this is supposed to happen,
0:08 so we come over here, clear that up a bit,
0:11 we can register and we can put in our information right here.
0:15 But this did nothing before because we had no account class,
0:18 and no data access, let's review.
0:21 So here is our account controller, and we have "signin" and we have "register".
0:25 Remember this follows the GET / POST / Redirect pattern and this is already fine,
0:32 we just went to that page and it looked great.
0:34 What we want to do is we want to register here
0:37 and let's just check the validation really quick,
0:39 it looks like the password and confirm password have to match
0:42 we have to have a password and we have to have some kind of email,
0:45 you might want to check that this is like matching the regular expression
0:47 or it's some kind of proper email, at least it has an @ and a dot in it.
0:51 Something like this.
0:53 OK, so now what we are going to do is we want to create the user here,
0:55 now we don't want to just allocate a new instance of an account,
0:58 set some properties and store it, this account creation and whatnot,
1:02 it's a little complex we are going to hash the passwords
1:05 and we're going to do a few other things as well,
1:09 like the other major parts of our data access, we're going to have a service
1:12 whose job is to manage all that stuff and here we're just going to call create account
1:16 on the service thing, so I am going to call this account_service,
1:19 it's going to handle things like generating password resets,
1:21 changing passwords, etc.
1:25 OK, we'll create a class, AccountService, and it's going to be mostly static stuff,
1:31 let's add a method here, called create_account.
1:37 Now, it's going to take the email, it's going to take the password,
1:41 I think everything else is auto-generated, the user only enters their email,
1:45 their password and the confirm password
1:47 which if they match, great, we'll just send one,
1:50 if they don't then we won't ever let them get here.
1:52 But I want to be very clear here that this is the plain text password,
1:56 this is not what we want to put into the database,
1:59 OK, so up here we're going to have to import the account and let's do it like this,
2:08 let's say "from that import account", I just want to work with that character right there
2:13 and we are also going to need the session,
2:16 so we're going to need to start out like everything we do by creating a db session,
2:22 so we'll say "session = that", and later we want a session.commit().
2:27 And somewhere in between what we want to do is
2:30 we want to say "account = Account", like that, and we could set, remember,
2:36 we could use keyword value arguments here
2:38 or we could just say "account.email = the email they passed in",
2:44 and account.password hash = I'm just going to write something bad for a minute,
2:50 hash plus plain text password, right.
2:53 The next thing we are going to do is talk about how to generate this,
2:55 this is just temporarily, please don't do this, just to show you
2:58 how this whole process is going to work.
3:01 So, there is one final step and that's going to be session.add(account). Like that.
3:06 Then we commit it, and then we're all done.
3:11 So we are going to actually come and create the user,
3:18 and this is not imported, is it?
3:20 It's cool, we've got auto-completion for anyway but we're going to need to import it for this to work.
3:24 Now the other thing to be careful here is this is actually not "return",
3:30 so just to use this thing here, we're going to print out the email address,
3:33 now, this should be complaining a little bit more,
3:36 because we're not actually returning the account, there we go, so we're returning it,
3:40 we'll be able to print this out here, so we have this step right here,
3:45 let me put this "send welcome email" down here
3:48 because we're not going to get to send welcome email until,
3:50 well we have email working there are we, but this part, this little step here, don't forget this.
3:54 There is a couple of places or ways which we could validate this,
3:57 so we're going to have to do something like this.
4:03 So here we want to do something like find the account by email, right,
4:06 this doesn't exist yet, we're going to write it in just a second, and,
4:10 if the account is not None, we want to do something like this,
4:14 vm.error "An account with this email already exists",
4:18 and we'll just stay on the same form, so we'll say like so,
4:22 remember how awesome our view models are? Well,
4:25 here they are being awesome again, so we are going to want to, this doesn't exist, we've got to write that,
4:28 we want to make sure that this is not already an account existing here for this email, right,
4:34 if they forgot they created account they might try to create it again
4:37 or if they have problems logging in, and they go maybe I never did create an account,
4:40 let me try and register, like "nope, you are going to need to reset your password",
4:43 something to that effect but here we've created it
4:46 and we probably want to log something interesting
4:48 but for now I am just going to print it out.
4:52 OK, so let's finish this little part right here, right,
4:54 this is why we create this account service,
4:57 there is going to be a bunch of these little helper methods, all to do with accounts,
5:01 and we can just stash them here, use them throughout our app
5:03 and forget about it and not make really complicated action methods.
5:08 Alright, so again, we are going to need the session but this time instead of doing an insert
5:11 we're going to do a query.
5:13 So we'll say account = session.query(Account), we want to do a filter
5:26 OK, so we are going to get just the first one, now we could do one
5:30 but I think one will throw an exception of None is found
5:33 and ideally, one won't be found in our particular use case here.
5:37 So first is better. Now we are not just going to use this for the register method,
5:40 we're going to use this for login, we're going to use this for all sorts of things
5:43 but we need it for register right now, so we're going to go ahead and write this,
5:47 there is one thing you might want to be careful of,
5:50 what if there is a space in their email, right?
5:52 When they entered it in the form, there was a little space,
5:55 or maybe it's upper case and you want a lower case, something like that,
6:00 so we've got to be really careful here maybe we'll do a test,
6:02 we could do this in our view model, but the emails could come from all over the place
6:06 not just that one view model, so let's make sure this particular method is durable
6:09 under bad inputs, so we'll say something like this, "if not email",
6:15 so if there is nothing here, we're just going to return None,
6:18 so there is going to be no account, it's empty,
6:20 remember that's not nullable, and then we can just say this.
6:27 Get the little case version, strip off all the white space,
6:30 and then we'll go through our little database trick here.
6:32 Great, I think we are ready to roll, let's give this a test, in fact, let's debug it,
6:37 we'll step through our little account register step.
6:41 Alright, are you guys ready to register?
6:43 I am here we go, OK, my email address is going to be let's say this one,
6:48 it doesn't really matter, it's going to be test
6:51 and this will be test two, we'll just make sure our matching email works,
6:54 so we come down here nope, it didn't validate, alright, let it go,
7:01 the password and confirmation don't match, OK let's just make this test one more time,
7:05 I am going to step over, this time it should validate, alright,
7:08 so we're going to run this find_account_by_email, notice it came back None, right here,
7:12 that's good, we don't have an existing account,
7:16 we just created the account, inserted into the database, we get back,
7:21 now we have this account, let's open it up and have a look,
7:24 here we have our id look, the id is this big giant thing created as well,
7:27 here is what day and time it is right now, here is the email address I use, and so on.
7:32 Great, so I am just going to let it go,
7:34 and we should have redirected to your account.
7:36 Yes, it works. Now of course, we did not hash the password,
7:40 we are going to talk about that next, let's just look really quick.
7:45 Here we got our id, and this and our HASH:test password,
7:49 not the best password there is but that is OK.
7:52 Very cool. Let's try to log in again with this, and just test our code
7:56 make sure we are getting that one object back, so let's go,
8:01 now, notice this still says sign in and register,
8:03 we haven't managed the whether or not the user is logged in within our web app,
8:07 within the database, it's all done so let's put the same email address
8:10 and test, and test, register, and it's going to come down here
8:14 and hopefully our little test about creating an account that exists,
8:18 oh look, here is an account that already exists by that same email address,
8:22 so guess what, there is a problem, this account already exists, let's go tell the user.
8:27 Well, you can't register, that account already exists.