Building Data-Driven Web Apps with Pyramid and SQLAlchemy Transcripts
Chapter: Client and server-side validation
Lecture: The viewmodel design pattern

Login or purchase this course to watch this video and the rest of the course contents.
0:00 You've seen view models in action let's review them as a concept. When you look at a web application at a very high level
0:08 we have the browser and our job is to send HTML to it. In this case, the HTML defined a form that's going to be submitted back.
0:16 So you see we're doing HTTP POST to register. And there's some data being passed along. Now in a naive sense we might write a really complicated
0:26 long method to process this register request. So here is a big action method. Why is it big? It has to get all the data out of the form.
0:35 Let's imagine, there's six or seven fields it's got to pull out of there. It has to validate them. If they don't validate
0:41 it has to send back an error message. And then, and only then does it actually do what it's supposed to do register the user. So that's a lot of work.
0:49 And it makes these methods hard to test it makes them hard to read hard to maintain, error prone and so on. If we could separate that
0:57 if we could put the place where we get the data from the form and validate it and make that the sole purpose of the entire file
1:05 is to validate the register form well then, that's way easier. Way easier to test and we can separate the validation and getting of the data
1:12 from the other things. We move that validation and that data acquisition apart and put it somewhere else into this thing we call a view model.
1:19 So we still have out action method but now the view model knows about the data exchange, it does that. It knows about the validation.
1:26 And we just have the action method work with this. The action method now becomes sort of orchestration
1:31 for the high level steps that need to happen here. So at a high level this is what the view model pattern looks like. Let's see how it makes things
1:39 simpler when we use it. So over here, we're going to look inside that register method, and like I said in theory, it could be really complicated.
1:48 But in practice because we're using view models it's quite simple. We have the get post redirect pattern still
1:53 so the top register under score get, this shows the form and it doesn't matter how many fields there are, what default data has to be there
2:01 it's basically just going to look like this. Register view model and pass off the to_dict stuff. It's up to the view model
2:09 to make sure the default data is there. Things like, data that drives dropdowns are there and so on. So this is pretty much it.
2:16 And then when we go and do our post again, we're going to go to our view model we're going to pass it the request
2:23 it's going to now validate that, right? We don't need to validate it in the GET because it's empty, it's always going to have errors like
2:29 "Your name's missing" Yeah, I know 'cause we're showing the form. But here we need to validate it. And then we just check. Anything go wrong?
2:36 Well, show them the error message and give them back their data. That's super easy. Doesn't matter how many thesis' there are
2:43 how much validation there is this is what we do. And then we actually do the thing we're trying to do in this case, register the user
2:50 based on the data we already have. We know we have it because it passed the validation on the line above that if statement above.
2:56 But if it failed, we'll just set another error message and pass that back. If it succeeds, here's the redirect part of the get post redirect pattern.
3:04 We've now registered them as a user and we just send them back to / or /account or welcome or where ever we send them to.
3:12 This code is super easy to test and it's very maintainable. Moreover, you know exactly where to go to look at the validation and data exchange
3:20 for registering. It's in viewmodels/account/registration/viewmodel. Boom, really nice design pattern and here it is in action.

Talk Python's Mastodon Michael Kennedy's Mastodon