title
Python Flask Tutorial: Full-Featured Web App Part 3 - Forms and User Input

description
In this Python Flask Tutorial, we will be learning how to create forms and accept user input. We will also learn how to validate that user input and notify the user if the input was invalid. Let's get started... The code for this series can be found at: https://github.com/CoreyMSchafer/code_snippets/tree/master/Python/Flask_Blog ✅ Support My Channel Through Patreon: https://www.patreon.com/coreyms ✅ Become a Channel Member: https://www.youtube.com/channel/UCCezIgC97PvUuR4_gbFUs5g/join ✅ One-Time Contribution Through PayPal: https://goo.gl/649HFY ✅ Cryptocurrency Donations: Bitcoin Wallet - 3MPH8oY2EAgbLVy7RBMinwcBntggi7qeG3 Ethereum Wallet - 0x151649418616068fB46C3598083817101d3bCD33 Litecoin Wallet - MPvEBY5fxGkmPQgocfJbxP6EmTo5UUXMot ✅ Corey's Public Amazon Wishlist http://a.co/inIyro1 ✅ Equipment I Use and Books I Recommend: https://www.amazon.com/shop/coreyschafer ▶️ You Can Find Me On: My Website - http://coreyms.com/ My Second Channel - https://www.youtube.com/c/coreymschafer Facebook - https://www.facebook.com/CoreyMSchafer Twitter - https://twitter.com/CoreyMSchafer Instagram - https://www.instagram.com/coreymschafer/ #Python #Flask

detail
{'title': 'Python Flask Tutorial: Full-Featured Web App Part 3 - Forms and User Input', 'heatmap': [{'end': 120.798, 'start': 84.955, 'weight': 0.912}, {'end': 761.085, 'start': 602.12, 'weight': 0.889}, {'end': 1367.339, 'start': 1274.024, 'weight': 0.741}, {'end': 1452.497, 'start': 1411.747, 'weight': 0.727}, {'end': 1537.422, 'start': 1505.745, 'weight': 0.772}, {'end': 1680.189, 'start': 1616.997, 'weight': 0.738}, {'end': 1739.477, 'start': 1703.221, 'weight': 0.745}, {'end': 1887.829, 'start': 1823.746, 'weight': 0.964}], 'summary': 'This tutorial on flask covers creating forms and user validation, working with wt forms extension, defining form fields, registering and logging in routes, styling form fields with html, css, and bootstrap, handling form submission, setting up form validation, and providing user feedback, emphasizing the use of the latest python version and upcoming topics on database usage and user support.', 'chapters': [{'end': 51.636, 'segs': [{'end': 32.445, 'src': 'embed', 'start': 0.189, 'weight': 0, 'content': [{'end': 1.211, 'text': "Hey there, how's it going everybody?", 'start': 0.189, 'duration': 1.022}, {'end': 7.099, 'text': "In this video, we'll continue with our Flash series by learning how to create forms and also how to validate user input.", 'start': 1.591, 'duration': 5.508}, {'end': 15.151, 'text': "So the application that we're going to be creating is going to have the ability for users to create accounts, log in, make posts and log out,", 'start': 7.42, 'duration': 7.731}, {'end': 15.832, 'text': 'and things like that.', 'start': 15.151, 'duration': 0.681}, {'end': 23.938, 'text': 'And the first part of that process is to create a registration page where a user can create an account on the website and then be able to log in and log out.', 'start': 16.292, 'duration': 7.646}, {'end': 25.92, 'text': "And that's what we're going to be doing in this video.", 'start': 24.279, 'duration': 1.641}, {'end': 27.461, 'text': "So let's go ahead and get started.", 'start': 26.2, 'duration': 1.261}, {'end': 32.445, 'text': 'Now, if you were to create forms from scratch, then that can get pretty complicated pretty fast.', 'start': 27.802, 'duration': 4.643}], 'summary': 'Creating a flash application with user forms and validation.', 'duration': 32.256, 'max_score': 0.189, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ189.jpg'}, {'end': 57.138, 'src': 'embed', 'start': 33.066, 'weight': 2, 'content': [{'end': 39.191, 'text': 'You would have to put in different kinds of validation checks to make sure that the user was inserting information correctly.', 'start': 33.066, 'duration': 6.125}, {'end': 47.194, 'text': "You'd also have to make sure that their passwords matched and you might have to write some regular expressions to make sure that they entered a valid email and things like that.", 'start': 39.671, 'duration': 7.523}, {'end': 51.636, 'text': "But luckily this process is so common that we don't have to reinvent the wheel.", 'start': 47.854, 'duration': 3.782}, {'end': 55.437, 'text': 'There are extensions out there that have already put in all the hard work.', 'start': 52.216, 'duration': 3.221}, {'end': 57.138, 'text': "so that you don't have to.", 'start': 55.817, 'duration': 1.321}], 'summary': 'Implement validation checks for user input, including password matching and email format, leveraging existing extensions to avoid reinventing the wheel.', 'duration': 24.072, 'max_score': 33.066, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ33066.jpg'}], 'start': 0.189, 'title': 'Flash form creation', 'summary': 'Focuses on creating forms and user validation in the flash series, enabling users to create accounts, log in, make posts, and log out, streamlining the process through common validation checks and regular expressions.', 'chapters': [{'end': 51.636, 'start': 0.189, 'title': 'Creating forms and user validation in flash', 'summary': 'Focuses on creating forms and user validation in the flash series, enabling users to create accounts, log in, make posts, and log out, streamlining the process through common validation checks and regular expressions.', 'duration': 51.447, 'highlights': ['The application allows users to create accounts, log in, make posts, and log out.', 'Explaining the common processes for creating forms and user validation in the Flash series.', 'Streamlining the process through common validation checks and regular expressions.']}], 'duration': 51.447, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ189.jpg', 'highlights': ['The application allows users to create accounts, log in, make posts, and log out.', 'Explaining the common processes for creating forms and user validation in the Flash series.', 'Streamlining the process through common validation checks and regular expressions.']}, {'end': 710.195, 'segs': [{'end': 84.935, 'src': 'embed', 'start': 52.216, 'weight': 0, 'content': [{'end': 55.437, 'text': 'There are extensions out there that have already put in all the hard work.', 'start': 52.216, 'duration': 3.221}, {'end': 57.138, 'text': "so that you don't have to.", 'start': 55.817, 'duration': 1.321}, {'end': 64.141, 'text': "and the most popular extension for working with forms and flask is called wt forms, and that's what we're going to be using in this video.", 'start': 57.138, 'duration': 7.003}, {'end': 67.883, 'text': 'so first we have to install this, and we can do this with a simple pip install.', 'start': 64.141, 'duration': 3.742}, {'end': 72.005, 'text': "so i'm here within my virtual environment, but you could also do this without a virtual environment.", 'start': 67.883, 'duration': 4.122}, {'end': 78.829, 'text': 'so i will say pip install, and that is flask, dash wtf for wt forms.', 'start': 72.005, 'duration': 6.824}, {'end': 84.935, 'text': "so we'll run that and go through the installation, And once that's installed, I'm going to open up our existing project and our text editor.", 'start': 78.829, 'duration': 6.106}], 'summary': "Wtforms is the popular extension for working with forms and flask, which can be installed with a simple 'pip install'.", 'duration': 32.719, 'max_score': 52.216, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ52216.jpg'}, {'end': 120.798, 'src': 'heatmap', 'start': 84.955, 'weight': 0.912, 'content': [{'end': 87.157, 'text': "So I'm going to open up Sublime Text here.", 'start': 84.955, 'duration': 2.202}, {'end': 90.621, 'text': "And now let's create a file where we can put these forms.", 'start': 87.598, 'duration': 3.023}, {'end': 93.585, 'text': "So I'm going to create another file in our project directory.", 'start': 90.922, 'duration': 2.663}, {'end': 97.249, 'text': "And I'm going to call this forms.py.", 'start': 94.125, 'duration': 3.124}, {'end': 102.872, 'text': "Now these forms could go directly into that application module that we've been writing,", 'start': 99.111, 'duration': 3.761}, {'end': 106.954, 'text': "but it's best to split things like this out into their own files so that everything has its own place.", 'start': 102.872, 'duration': 4.082}, {'end': 111.095, 'text': 'That way, if we need to update a form in the future, then we know exactly where to look.', 'start': 107.474, 'duration': 3.621}, {'end': 114.436, 'text': "So it's better to have this stuff split up into smaller,", 'start': 111.795, 'duration': 2.641}, {'end': 120.798, 'text': 'more manageable sections of code rather than one larger application file where everything is in one place and hard to find.', 'start': 114.436, 'duration': 6.362}], 'summary': 'Creating separate forms.py file for better organization and manageability.', 'duration': 35.843, 'max_score': 84.955, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ84955.jpg'}, {'end': 453.949, 'src': 'embed', 'start': 424.05, 'weight': 1, 'content': [{'end': 430.234, 'text': "So let's pass in validators, and the only one that we want for this is going to be data required.", 'start': 424.05, 'duration': 6.184}, {'end': 435.838, 'text': "I mean you could do a minimum length on this if you want, but we won't for this specific application.", 'start': 430.234, 'duration': 5.604}, {'end': 438.799, 'text': 'okay, and now we also want a password confirmation.', 'start': 435.838, 'duration': 2.961}, {'end': 444.403, 'text': "so that's basically going to be the same as this field here, but a little bit different.", 'start': 438.799, 'duration': 5.604}, {'end': 453.949, 'text': "so I'll just call this confirm password and for the label here I'll say confirm password and we will move these validators to the next line,", 'start': 444.403, 'duration': 9.546}], 'summary': 'Setting up validators for data required and password confirmation.', 'duration': 29.899, 'max_score': 424.05, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ424050.jpg'}, {'end': 654.761, 'src': 'embed', 'start': 621.269, 'weight': 3, 'content': [{'end': 625.593, 'text': 'now, when we use these forms, We need to set a secret key for our application.', 'start': 621.269, 'duration': 4.324}, {'end': 631.74, 'text': 'A secret key will protect against modifying cookies and cross-site request forgery attacks and things like that.', 'start': 625.994, 'duration': 5.746}, {'end': 633.402, 'text': "It's simple to do.", 'start': 632.481, 'duration': 0.921}, {'end': 637.346, 'text': 'We just need to go to the top of our application file here.', 'start': 633.522, 'duration': 3.824}, {'end': 644.753, 'text': 'and right under our app variable, we can set a secret key by saying app.config,', 'start': 637.987, 'duration': 6.766}, {'end': 654.761, 'text': 'and that is how you set config values on our application and this is going to be the secret key and we will set this equal to an empty string.', 'start': 644.753, 'duration': 10.008}], 'summary': 'Set a secret key to protect against attacks. set in app.config as empty string.', 'duration': 33.492, 'max_score': 621.269, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ621269.jpg'}], 'start': 52.216, 'title': 'Flask forms and python form creation', 'summary': 'Covers working with wt forms extension in flask, covering installation, creating form classes, and defining form fields. it also explores using validators in python form creation for implementing data required, length, email, password, confirm password, submit, boolean fields, and setting a secret key.', 'chapters': [{'end': 247.594, 'start': 52.216, 'title': 'Working with forms in flask', 'summary': 'Discusses using the popular wt forms extension for working with forms in flask, including installation, creating form classes, and defining form fields, to ensure proper organization and management of code.', 'duration': 195.378, 'highlights': ['The chapter discusses using the popular wt forms extension for working with forms in flask Highlights the focus of the chapter and the primary tool being used for form handling.', 'including installation, creating form classes, and defining form fields Summarizes the key actions involved in using wt forms, including installation and creating form classes with defined form fields.', 'to ensure proper organization and management of code Emphasizes the importance of splitting forms into separate files for better code management and future updates.']}, {'end': 710.195, 'start': 247.954, 'title': 'Using validators in python form creation', 'summary': 'Discusses the use of validators in python form creation, including implementing data required, length, email, password, confirm password, submit, boolean fields, and setting a secret key, for form validation and security.', 'duration': 462.241, 'highlights': ['Implementing various validators such as data required, length, email, password, confirm password, submit, boolean fields for form validation The chapter covers the implementation of various validators such as data required, length, email, password, confirm password, submit, boolean fields for form validation.', 'Setting a secret key for application security It explains the process of setting a secret key for application security to protect against modifying cookies and cross-site request forgery attacks.', 'Using the secrets module to generate a random string for the secret key Demonstrates the usage of the secrets module to generate a random string for the secret key using the token hex method.']}], 'duration': 657.979, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ52216.jpg', 'highlights': ['The chapter discusses using the popular wt forms extension for working with forms in flask Highlights the focus of the chapter and the primary tool being used for form handling.', 'Implementing various validators such as data required, length, email, password, confirm password, submit, boolean fields for form validation The chapter covers the implementation of various validators such as data required, length, email, password, confirm password, submit, boolean fields for form validation.', 'including installation, creating form classes, and defining form fields Summarizes the key actions involved in using wt forms, including installation and creating form classes with defined form fields.', 'Setting a secret key for application security It explains the process of setting a secret key for application security to protect against modifying cookies and cross-site request forgery attacks.']}, {'end': 980.36, 'segs': [{'end': 761.085, 'src': 'embed', 'start': 710.595, 'weight': 0, 'content': [{'end': 714.221, 'text': "Okay, so now let's use those forms that we created here in our application.", 'start': 710.595, 'duration': 3.626}, {'end': 716.724, 'text': 'So first, we need to import those forms.', 'start': 714.561, 'duration': 2.163}, {'end': 719.849, 'text': 'And those are in the forms.py module.', 'start': 717.185, 'duration': 2.664}, {'end': 723.614, 'text': "So and it's within the same directory as this module here.", 'start': 720.189, 'duration': 3.425}, {'end': 725.857, 'text': 'So we can just import directly from that.', 'start': 723.934, 'duration': 1.923}, {'end': 728.841, 'text': 'So we can say from forms import.', 'start': 725.957, 'duration': 2.884}, {'end': 732.747, 'text': 'And that was the registration form.', 'start': 729.422, 'duration': 3.325}, {'end': 734.028, 'text': 'Make sure I spell that correctly.', 'start': 732.887, 'duration': 1.141}, {'end': 736.311, 'text': 'And the login form.', 'start': 734.569, 'duration': 1.742}, {'end': 742.555, 'text': "And now let's create some routes for our registration and login so that we can see how these get converted to HTML.", 'start': 736.852, 'duration': 5.703}, {'end': 745.457, 'text': "So first let's create the registration route.", 'start': 742.895, 'duration': 2.562}, {'end': 752.52, 'text': "So down here above our main conditional, I'm going to create another route.", 'start': 745.757, 'duration': 6.763}, {'end': 761.085, 'text': "So I'll copy one of these existing ones and I will call this route register and we need to change the function name as well.", 'start': 752.54, 'duration': 8.545}], 'summary': 'Import and use registration and login forms in application, create routes for registration and login.', 'duration': 50.49, 'max_score': 710.595, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ710595.jpg'}, {'end': 863.485, 'src': 'embed', 'start': 833.697, 'weight': 2, 'content': [{'end': 835.599, 'text': 'We want the title to be login.', 'start': 833.697, 'duration': 1.902}, {'end': 841.68, 'text': "And we can say form equals form because now we're going to be passing in that instance of the login form.", 'start': 836.219, 'duration': 5.461}, {'end': 848.062, 'text': 'So now that we have these routes created, now we just need to create the templates that use these form variables that we just passed in.', 'start': 842.04, 'duration': 6.022}, {'end': 850.342, 'text': "So let's go ahead and create those templates.", 'start': 848.422, 'duration': 1.92}, {'end': 854.943, 'text': 'So up here in my templates directory, I am going to create two new files.', 'start': 850.662, 'duration': 4.281}, {'end': 863.485, 'text': 'So I will create register.html and I will also create a new file called login.html.', 'start': 855.283, 'duration': 8.202}], 'summary': 'Create templates for login and register forms.', 'duration': 29.788, 'max_score': 833.697, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ833697.jpg'}, {'end': 933.136, 'src': 'embed', 'start': 904.677, 'weight': 3, 'content': [{'end': 906.758, 'text': 'that will just make this look a little nicer.', 'start': 904.677, 'duration': 2.081}, {'end': 909.18, 'text': 'and now we want to open up a form tag.', 'start': 906.758, 'duration': 2.422}, {'end': 919.346, 'text': "so we'll say form and we want the method of this form to be equal to post and we want the action here.", 'start': 909.18, 'duration': 10.166}, {'end': 922.408, 'text': "we'll just set the action equal to an empty string.", 'start': 919.346, 'duration': 3.062}, {'end': 926.791, 'text': "now that means that when we post this form, it's just going to go back to the same route.", 'start': 922.408, 'duration': 4.383}, {'end': 929.973, 'text': "it's going to post that information to the same route that we're currently on.", 'start': 927.071, 'duration': 2.902}, {'end': 933.136, 'text': "Okay, so now we're ready to start putting in some form fields here.", 'start': 930.294, 'duration': 2.842}], 'summary': "Creating a form with 'post' method and empty action for posting information to the same route.", 'duration': 28.459, 'max_score': 904.677, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ904677.jpg'}, {'end': 997.837, 'src': 'embed', 'start': 966.557, 'weight': 4, 'content': [{'end': 972.658, 'text': 'And when I said earlier that setting our secret key for our application would protect our form against certain attacks.', 'start': 966.557, 'duration': 6.101}, {'end': 975.819, 'text': 'Well, this hidden tag here is part of that protection.', 'start': 973.278, 'duration': 2.541}, {'end': 980.36, 'text': "So add it in, but you don't need to worry about the underlying details, but you definitely need it.", 'start': 976.159, 'duration': 4.201}, {'end': 989.949, 'text': "Okay, so now let's add in our other form fields here and I'm also going to add a couple of HTML and CSS classes here as well.", 'start': 980.74, 'duration': 9.209}, {'end': 997.837, 'text': "So I'll add a field set and we'll set a class here equal to form group and this is all bootstrap stuff just to make this look a little nicer.", 'start': 990.269, 'duration': 7.568}], 'summary': 'Adding a hidden tag for form protection and styling with html and css classes.', 'duration': 31.28, 'max_score': 966.557, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ966557.jpg'}], 'start': 710.595, 'title': 'Creating registration and login routes and adding form fields to content section', 'summary': 'Explores importing forms from forms.py module, creating registration and login routes, and preparing templates, then covers adding form fields to the content section including setting the method and action for the form, and adding a hidden tag for csrf token protection.', 'chapters': [{'end': 881.418, 'start': 710.595, 'title': 'Creating registration and login routes', 'summary': 'Explores importing forms from forms.py module, creating registration and login routes, and preparing templates to use form variables.', 'duration': 170.823, 'highlights': ['Importing forms from forms.py module The forms for registration and login are imported from the forms.py module within the same directory as the main module.', 'Creating registration and login routes New routes for registration and login are created, and instances of the respective forms are prepared to be sent to the application.', 'Preparing templates to use form variables Templates for register.html and login.html are created to use the form variables passed in, allowing access to the form instances within the templates.']}, {'end': 980.36, 'start': 881.819, 'title': 'Adding form fields to content section', 'summary': 'Covers adding form fields to the content section of the page, including setting the method and action for the form, and adding a hidden tag for csrf token protection.', 'duration': 98.541, 'highlights': ["Setting the method of the form to 'post' and the action to an empty string, which means the form will post to the current route.", 'Explaining the purpose of the hidden tag as a CSRF token for protection against certain attacks and emphasizing its necessity.']}], 'duration': 269.765, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ710595.jpg', 'highlights': ['Importing forms from forms.py module The forms for registration and login are imported from the forms.py module within the same directory as the main module.', 'Creating registration and login routes New routes for registration and login are created, and instances of the respective forms are prepared to be sent to the application.', 'Preparing templates to use form variables Templates for register.html and login.html are created to use the form variables passed in, allowing access to the form instances within the templates.', "Setting the method of the form to 'post' and the action to an empty string, which means the form will post to the current route.", 'Explaining the purpose of the hidden tag as a CSRF token for protection against certain attacks and emphasizing its necessity.']}, {'end': 1569.857, 'segs': [{'end': 1004.882, 'src': 'embed', 'start': 980.74, 'weight': 2, 'content': [{'end': 989.949, 'text': "Okay, so now let's add in our other form fields here and I'm also going to add a couple of HTML and CSS classes here as well.", 'start': 980.74, 'duration': 9.209}, {'end': 997.837, 'text': "So I'll add a field set and we'll set a class here equal to form group and this is all bootstrap stuff just to make this look a little nicer.", 'start': 990.269, 'duration': 7.568}, {'end': 1001.78, 'text': 'And then we will pass in a legend.', 'start': 998.477, 'duration': 3.303}, {'end': 1004.882, 'text': 'So this is going to be the legend for our register form.', 'start': 1002.1, 'duration': 2.782}], 'summary': 'Adding form fields, html and css classes for a register form.', 'duration': 24.142, 'max_score': 980.74, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ980740.jpg'}, {'end': 1148.392, 'src': 'embed', 'start': 1123.759, 'weight': 1, 'content': [{'end': 1132.664, 'text': "now we want the confirm password field, so we'll paste that in again and change both of these to confirm underscore password.", 'start': 1123.759, 'duration': 8.905}, {'end': 1141.368, 'text': "now, if you're wondering where I'm getting these field names here, these are the variable names that we specified here within our class.", 'start': 1132.664, 'duration': 8.704}, {'end': 1145.791, 'text': 'so we want all of those to be equal to these variable names here.', 'start': 1141.368, 'duration': 4.423}, {'end': 1148.392, 'text': 'so go back to that register template.', 'start': 1145.791, 'duration': 2.601}], 'summary': 'Creating confirm password field and updating variable names in the class.', 'duration': 24.633, 'max_score': 1123.759, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ1123759.jpg'}, {'end': 1216.904, 'src': 'embed', 'start': 1191.956, 'weight': 3, 'content': [{'end': 1201.129, 'text': "So we'll say class is equal to and we want a button class on this btn and also btn outline, dash info.", 'start': 1191.956, 'duration': 9.173}, {'end': 1206.777, 'text': "And that's like in Bootstrap, that's a nice little bluish outline button that they will style for you.", 'start': 1201.149, 'duration': 5.628}, {'end': 1208.918, 'text': 'Okay, so that will do it for our form.', 'start': 1207.097, 'duration': 1.821}, {'end': 1216.904, 'text': "Now, since we're on the register page, you'll see on a lot of websites they'll have on the register page it'll say you know,", 'start': 1209.259, 'duration': 7.645}], 'summary': 'Using bootstrap to create a styled bluish outline button for the form.', 'duration': 24.948, 'max_score': 1191.956, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ1191956.jpg'}, {'end': 1371.041, 'src': 'heatmap', 'start': 1264.777, 'weight': 6, 'content': [{'end': 1266.398, 'text': 'So this is going to be an anchor tag.', 'start': 1264.777, 'duration': 1.621}, {'end': 1273.584, 'text': "I'll give this anchor tag a class of a margin left of two, just to give it some spacing from that text there.", 'start': 1266.718, 'duration': 6.866}, {'end': 1279.248, 'text': 'And now we want an href equal to, and we want this to link to our login page.', 'start': 1274.024, 'duration': 5.224}, {'end': 1284.873, 'text': "So remember, if you want to link somewhere, it's always a good idea to use the URL for function.", 'start': 1279.528, 'duration': 5.345}, {'end': 1287.655, 'text': "So we'll say URL underscore for.", 'start': 1285.193, 'duration': 2.462}, {'end': 1292.762, 'text': 'and we want to pass in the link to the login page.', 'start': 1288.215, 'duration': 4.547}, {'end': 1301.135, 'text': "Now just remember that the value that we're passing in to the URL for function is not the name of the route, it's the name of the route function.", 'start': 1293.083, 'duration': 8.052}, {'end': 1307.042, 'text': 'So if I go back to our application, we are actually passing in this value here, not this.', 'start': 1301.416, 'duration': 5.626}, {'end': 1309.264, 'text': 'So we want the name of the function.', 'start': 1307.402, 'duration': 1.862}, {'end': 1311.545, 'text': "So that's what we have there.", 'start': 1309.604, 'duration': 1.941}, {'end': 1314.628, 'text': 'And now we need to close out this anchor tag.', 'start': 1311.926, 'duration': 2.702}, {'end': 1320.713, 'text': "So I will give this text, I'll say, you know, just sign in and then close out that anchor tag there.", 'start': 1314.888, 'duration': 5.825}, {'end': 1324.135, 'text': "Okay, so it's been a while since we viewed our application in the browser.", 'start': 1321.073, 'duration': 3.062}, {'end': 1327.957, 'text': "So let's save what we have now and see what we get so far.", 'start': 1324.455, 'duration': 3.502}, {'end': 1329.898, 'text': 'So let me save this.', 'start': 1328.337, 'duration': 1.561}, {'end': 1338.142, 'text': 'And now if I go back to our command line, then we can run our current application by saying Python and then the name of our application.', 'start': 1330.138, 'duration': 8.004}, {'end': 1339.843, 'text': "So we didn't get any errors.", 'start': 1338.702, 'duration': 1.141}, {'end': 1340.483, 'text': "So that's good.", 'start': 1339.903, 'duration': 0.58}, {'end': 1342.665, 'text': "So let's open up our page.", 'start': 1340.643, 'duration': 2.022}, {'end': 1345.827, 'text': 'So that was localhost on port 5000.', 'start': 1343.005, 'duration': 2.822}, {'end': 1352.27, 'text': "And now let's go to that register page that we just created and see if we get that form.", 'start': 1345.827, 'duration': 6.443}, {'end': 1355.132, 'text': "So I'll say register and go to that form.", 'start': 1352.591, 'duration': 2.541}, {'end': 1357.133, 'text': 'And we can see that this looks pretty good so far.', 'start': 1355.452, 'duration': 1.681}, {'end': 1359.415, 'text': 'So we have our form legend here.', 'start': 1357.213, 'duration': 2.202}, {'end': 1364.177, 'text': 'And then it did get all of those forms that we created in our forms file.', 'start': 1359.815, 'duration': 4.362}, {'end': 1367.339, 'text': 'So we have our username, email, password, and confirm password.', 'start': 1364.197, 'duration': 3.142}, {'end': 1371.041, 'text': 'And down here is that link where it says already have an account, sign in.', 'start': 1367.479, 'duration': 3.562}], 'summary': 'Creating anchor tag to link to login page, checking application in browser, successful form creation', 'duration': 106.264, 'max_score': 1264.777, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ1264777.jpg'}, {'end': 1452.497, 'src': 'heatmap', 'start': 1411.747, 'weight': 0.727, 'content': [{'end': 1419.432, 'text': 'So if I go back to Sublime here and go to our Flask application file up to our register route,', 'start': 1411.747, 'duration': 7.685}, {'end': 1426.497, 'text': 'then we can add a list of allowed methods by passing in an argument of methods is equal to.', 'start': 1419.432, 'duration': 7.065}, {'end': 1430.18, 'text': 'this is going to be a list and we want this to be equal to get.', 'start': 1426.497, 'duration': 3.683}, {'end': 1433.222, 'text': 'so it accepts get requests and also post.', 'start': 1430.18, 'duration': 3.042}, {'end': 1436.084, 'text': 'so it accepts post requests, which is what we just made in the browser.', 'start': 1433.222, 'duration': 2.862}, {'end': 1445.371, 'text': 'So now if I save that, and go back to our browser and then reload our register page and we can fill this out again.', 'start': 1436.464, 'duration': 8.907}, {'end': 1452.497, 'text': "I'll just fill it out with some sample values here really fast and then hit the submit button.", 'start': 1445.391, 'duration': 7.106}], 'summary': 'In the flask application file, the register route now accepts get and post requests.', 'duration': 40.75, 'max_score': 1411.747, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ1411747.jpg'}, {'end': 1445.371, 'src': 'embed', 'start': 1419.432, 'weight': 0, 'content': [{'end': 1426.497, 'text': 'then we can add a list of allowed methods by passing in an argument of methods is equal to.', 'start': 1419.432, 'duration': 7.065}, {'end': 1430.18, 'text': 'this is going to be a list and we want this to be equal to get.', 'start': 1426.497, 'duration': 3.683}, {'end': 1433.222, 'text': 'so it accepts get requests and also post.', 'start': 1430.18, 'duration': 3.042}, {'end': 1436.084, 'text': 'so it accepts post requests, which is what we just made in the browser.', 'start': 1433.222, 'duration': 2.862}, {'end': 1445.371, 'text': 'So now if I save that, and go back to our browser and then reload our register page and we can fill this out again.', 'start': 1436.464, 'duration': 8.907}], 'summary': 'The code now accepts both get and post requests, enhancing functionality.', 'duration': 25.939, 'max_score': 1419.432, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ1419432.jpg'}, {'end': 1537.422, 'src': 'heatmap', 'start': 1485.875, 'weight': 4, 'content': [{'end': 1497.24, 'text': "so I'll say if form dot, validate on submit And, as you can probably tell by the name, this will tell us if our form validated when it was submitted.", 'start': 1485.875, 'duration': 11.365}, {'end': 1500.542, 'text': "So now I'm going to use something called a flash message.", 'start': 1497.561, 'duration': 2.981}, {'end': 1505.385, 'text': 'A flash message in Flask is an easy way for us to send a one time alert.', 'start': 1500.923, 'duration': 4.462}, {'end': 1509.487, 'text': "So first I'll have to import this and this is from Flask.", 'start': 1505.745, 'duration': 3.742}, {'end': 1515.591, 'text': 'So from Flask I will import flash and then come back down here to our conditional.', 'start': 1509.848, 'duration': 5.743}, {'end': 1519.973, 'text': "And now we can add the message that we want to display when we've created a user successfully.", 'start': 1515.951, 'duration': 4.022}, {'end': 1528.537, 'text': "So I will say flash and pass in a message of and this is going to be an F string here since I'm going to pass in a variable.", 'start': 1520.293, 'duration': 8.244}, {'end': 1537.422, 'text': "So I'll say account created for and then we will pass in the form dot username dot data.", 'start': 1528.877, 'duration': 8.545}], 'summary': 'Using flask to generate a flash message upon successful user creation.', 'duration': 23.612, 'max_score': 1485.875, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ1485875.jpg'}, {'end': 1569.857, 'src': 'embed', 'start': 1537.782, 'weight': 5, 'content': [{'end': 1540.283, 'text': "Then we'll put an exclamation point after that as well.", 'start': 1537.782, 'duration': 2.501}, {'end': 1546.046, 'text': "Now, I'm using Python 3.6, and that's why I can use this F string here.", 'start': 1540.743, 'duration': 5.303}, {'end': 1552.749, 'text': "I suggest that everyone use the latest version that they can, but if you're still below Python 3.6,", 'start': 1546.786, 'duration': 5.963}, {'end': 1558.772, 'text': "then you're going to have to use the format method on that string to fill in that placeholder instead of this F string,", 'start': 1552.749, 'duration': 6.023}, {'end': 1561.353, 'text': 'because the F strings are only Python 3.6 and above.', 'start': 1558.772, 'duration': 2.581}, {'end': 1563.994, 'text': "So if you get an error there, then that's probably what it is.", 'start': 1561.653, 'duration': 2.341}, {'end': 1569.857, 'text': 'Okay, so now we have a flashed message here, but I want to be able to tell the difference between the different kinds of alerts.', 'start': 1564.334, 'duration': 5.523}], 'summary': 'Using python 3.6 allows for f-string, below 3.6 use format method.', 'duration': 32.075, 'max_score': 1537.782, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ1537782.jpg'}], 'start': 980.74, 'title': 'Creating and styling form fields, registration form in bootstrap, and handling form submission in flask', 'summary': 'Covers creating and styling form fields with html, css, and bootstrap, including creating a registration form in bootstrap with layout and functionality checks, and handling form submission in a flask application with method validation, data validation, and flash messages. it emphasizes using the latest python version for f strings.', 'chapters': [{'end': 1168.935, 'start': 980.74, 'title': 'Creating form fields and styling with html and css', 'summary': 'Covers the process of adding form fields, applying html and css classes, and using bootstrap to style the form, with detailed instructions on adding labels and classes to each form field.', 'duration': 188.195, 'highlights': ['The chapter explains how to add form fields and apply HTML and CSS classes to enhance the styling, with a focus on using bootstrap to improve the appearance of the form.', "Detailed instructions are provided for adding labels and classes to each form field, including specific examples such as setting classes like 'form-control' and 'form-control-lg' to enhance the visual display of the form fields.", 'The transcript provides a step-by-step guide for adding form fields for username, email, password, and confirm password, aligning with the variable names specified within the class.']}, {'end': 1374.543, 'start': 1168.935, 'title': 'Creating a registration form in bootstrap', 'summary': 'Covers creating a registration form in bootstrap, including adding form elements, styling buttons, and adding a link to the login page. it also includes viewing the application in the browser and checking the form layout and functionality.', 'duration': 205.608, 'highlights': ["Adding form elements and styling buttons in Bootstrap The chapter explains adding form elements and styling buttons in Bootstrap, including specifying classes for the submit button like 'btn' and 'btn-outline-info' to create a bluish outline button.", "Adding a link to the login page The chapter covers adding a link to the login page using an anchor tag with a class of 'margin-left-2' and an href attribute linking to the login page using the URL_for function.", 'Viewing the application in the browser and checking the form layout and functionality The chapter describes viewing the application in the browser, running the current application using Python, and checking the form layout and functionality by accessing the register page.']}, {'end': 1569.857, 'start': 1374.603, 'title': 'Handling form submission in flask', 'summary': 'Explains how to handle form submission in a flask application, including adding allowed methods to the route, validating form data, and using flash messages to display alerts. it also highlights the importance of using the latest python version for f strings.', 'duration': 195.254, 'highlights': ["The chapter emphasizes the need to add allowed methods (GET and POST) to the route in order to handle form submission, resolving the 'method not allowed' error.", "It explains the process of validating form data using the 'validate on submit' method and utilizing flash messages in Flask to display one-time alerts.", 'The chapter also mentions the use of F strings for formatting messages in Python 3.6 and above, highlighting the benefits of using the latest Python version.', 'The transcript illustrates the process of handling form submission in a Flask application, showcasing the steps to address errors and ensure proper validation of form data.']}], 'duration': 589.117, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ980740.jpg', 'highlights': ["The chapter emphasizes the need to add allowed methods (GET and POST) to the route in order to handle form submission, resolving the 'method not allowed' error.", 'The transcript provides a step-by-step guide for adding form fields for username, email, password, and confirm password, aligning with the variable names specified within the class.', 'The chapter explains how to add form fields and apply HTML and CSS classes to enhance the styling, with a focus on using bootstrap to improve the appearance of the form.', "The chapter explains adding form elements and styling buttons in Bootstrap, including specifying classes for the submit button like 'btn' and 'btn-outline-info' to create a bluish outline button.", "It explains the process of validating form data using the 'validate on submit' method and utilizing flash messages in Flask to display one-time alerts.", 'The chapter also mentions the use of F strings for formatting messages in Python 3.6 and above, highlighting the benefits of using the latest Python version.', "Adding a link to the login page The chapter covers adding a link to the login page using an anchor tag with a class of 'margin-left-2' and an href attribute linking to the login page using the URL_for function."]}, {'end': 2210.438, 'segs': [{'end': 1616.997, 'src': 'embed', 'start': 1570.217, 'weight': 0, 'content': [{'end': 1579.606, 'text': 'so bootstrap has different alert styles for successes and warnings and errors and the flask function accepts a second argument that is called a category.', 'start': 1570.217, 'duration': 9.389}, {'end': 1586.252, 'text': "so i'm going to pass in the name of the bootstrap class that i want this alert to have, and that is success.", 'start': 1579.606, 'duration': 6.646}, {'end': 1595.221, 'text': "so i'll put in a comma and pass in a second argument to this flash function here, and this is going to be the string success, okay,", 'start': 1586.252, 'duration': 8.969}, {'end': 1599.785, 'text': "and now that we've got our flash message now let's redirect the user to a different page,", 'start': 1595.221, 'duration': 4.564}, {'end': 1605.19, 'text': "because you don't want to fill out a form and then just get redirected back to the same form after you submit it.", 'start': 1599.785, 'duration': 5.405}, {'end': 1608.132, 'text': 'that would be a little confusing for the user.', 'start': 1605.81, 'duration': 2.322}, {'end': 1611.093, 'text': 'so instead will redirect the user to the home page.', 'start': 1608.132, 'duration': 2.961}, {'end': 1616.997, 'text': "so to do this we're going to need to import the redirect function, and that is from flask.", 'start': 1611.093, 'duration': 5.904}], 'summary': 'Using bootstrap alerts, flask flash function, and redirecting users to the home page.', 'duration': 46.78, 'max_score': 1570.217, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ1570217.jpg'}, {'end': 1680.189, 'src': 'heatmap', 'start': 1616.997, 'weight': 0.738, 'content': [{'end': 1626.703, 'text': "so I'll come back up here to the top and after our last import I'll also import redirect then come back down here inside of our conditional.", 'start': 1616.997, 'duration': 9.706}, {'end': 1635.931, 'text': 'So when the form validates properly, we will say return redirect and we want to redirect to the URL for.', 'start': 1627.043, 'duration': 8.888}, {'end': 1637.853, 'text': 'so we use that URL for function again.', 'start': 1635.931, 'duration': 1.922}, {'end': 1641.416, 'text': 'And we want this to redirect to our homepage.', 'start': 1637.873, 'duration': 3.543}, {'end': 1645.099, 'text': 'And again, that is the name of the function for that route.', 'start': 1641.756, 'duration': 3.343}, {'end': 1646.881, 'text': "So we're redirecting to here.", 'start': 1645.119, 'duration': 1.762}, {'end': 1649.781, 'text': 'Okay, so this should all work except for one thing.', 'start': 1647.421, 'duration': 2.36}, {'end': 1654.142, 'text': "We haven't updated our template to actually show the flashed messages yet.", 'start': 1649.901, 'duration': 4.241}, {'end': 1660.283, 'text': "So I'm going to put this within our layout template so that flashed messages pop up on any page.", 'start': 1654.462, 'duration': 5.821}, {'end': 1669.345, 'text': "So I'm going to open up our layout.html and let's just assume that we want to display any of our flashed messages up here at the top of our content.", 'start': 1660.603, 'duration': 8.742}, {'end': 1673.966, 'text': 'So I will come down to our block content here.', 'start': 1669.665, 'duration': 4.301}, {'end': 1677.548, 'text': "And now right above this content, I'm going to display these messages.", 'start': 1674.306, 'duration': 3.242}, {'end': 1680.189, 'text': "So I'm going to open up a code block.", 'start': 1677.848, 'duration': 2.341}], 'summary': 'Updating template to display flashed messages on any page.', 'duration': 63.192, 'max_score': 1616.997, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ1616997.jpg'}, {'end': 1673.966, 'src': 'embed', 'start': 1645.119, 'weight': 2, 'content': [{'end': 1646.881, 'text': "So we're redirecting to here.", 'start': 1645.119, 'duration': 1.762}, {'end': 1649.781, 'text': 'Okay, so this should all work except for one thing.', 'start': 1647.421, 'duration': 2.36}, {'end': 1654.142, 'text': "We haven't updated our template to actually show the flashed messages yet.", 'start': 1649.901, 'duration': 4.241}, {'end': 1660.283, 'text': "So I'm going to put this within our layout template so that flashed messages pop up on any page.", 'start': 1654.462, 'duration': 5.821}, {'end': 1669.345, 'text': "So I'm going to open up our layout.html and let's just assume that we want to display any of our flashed messages up here at the top of our content.", 'start': 1660.603, 'duration': 8.742}, {'end': 1673.966, 'text': 'So I will come down to our block content here.', 'start': 1669.665, 'duration': 4.301}], 'summary': 'Updating layout template to display flashed messages on any page.', 'duration': 28.847, 'max_score': 1645.119, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ1645119.jpg'}, {'end': 1739.477, 'src': 'heatmap', 'start': 1703.221, 'weight': 0.745, 'content': [{'end': 1709.583, 'text': 'And we want to also pass in an argument here of with categories equal to true.', 'start': 1703.221, 'duration': 6.362}, {'end': 1719.047, 'text': 'Now that, with categories equal to true, will allow us to grab this success category that we passed in to that flashed message,', 'start': 1709.883, 'duration': 9.164}, {'end': 1721.708, 'text': "which is the bootstrap class that we're going to use.", 'start': 1719.047, 'duration': 2.661}, {'end': 1725.729, 'text': "And so now I'm going to close off this block.", 'start': 1722.008, 'duration': 3.721}, {'end': 1736.976, 'text': 'So I will put in a closed block here and say end with now within our block here.', 'start': 1726.089, 'duration': 10.887}, {'end': 1739.477, 'text': 'now we want to print out any messages.', 'start': 1736.976, 'duration': 2.501}], 'summary': "Passing 'with categories=true' argument helps grab success category for flashed message and print out any messages.", 'duration': 36.256, 'max_score': 1703.221, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ1703221.jpg'}, {'end': 1887.829, 'src': 'heatmap', 'start': 1823.746, 'weight': 0.964, 'content': [{'end': 1825.767, 'text': "And we'll see this in action in just a second.", 'start': 1823.746, 'duration': 2.021}, {'end': 1830.388, 'text': 'So now within this div, we want to actually print out this message.', 'start': 1826.087, 'duration': 4.301}, {'end': 1834.95, 'text': "So I'll just pass in our message variable within our curly braces there.", 'start': 1830.548, 'duration': 4.402}, {'end': 1840.573, 'text': "Okay, so now that we have all of that in place, let's make sure that it all works if our form validates properly.", 'start': 1835.29, 'duration': 5.283}, {'end': 1842.894, 'text': "So let's open back up our site.", 'start': 1840.913, 'duration': 1.981}, {'end': 1846.476, 'text': "Let's make sure that our server is still running and it's not.", 'start': 1843.014, 'duration': 3.462}, {'end': 1852.86, 'text': "So you might see this sometimes if you actually save your file and there's a syntax error at the time that you save it,", 'start': 1846.756, 'duration': 6.104}, {'end': 1855.842, 'text': 'then it might shut down your development server.', 'start': 1853.18, 'duration': 2.662}, {'end': 1859.706, 'text': 'so to run that again you can just rerun the file again.', 'start': 1855.842, 'duration': 3.864}, {'end': 1860.947, 'text': "so now we don't have any errors.", 'start': 1859.706, 'duration': 1.241}, {'end': 1861.808, 'text': "so that's good.", 'start': 1860.947, 'duration': 0.861}, {'end': 1867.593, 'text': "so let's go back to our site and reload our register page and load that up.", 'start': 1861.808, 'duration': 5.785}, {'end': 1871.757, 'text': "and now i'm going to fill out this form correctly so that it will validate.", 'start': 1867.593, 'duration': 4.164}, {'end': 1876.741, 'text': "so i'm going to pass in valid emails and passwords and all of that.", 'start': 1871.757, 'duration': 4.984}, {'end': 1880.444, 'text': 'and now, if i submit this valid form,', 'start': 1877.842, 'duration': 2.602}, {'end': 1887.829, 'text': 'then we can see that we got redirected back to our home page with our flash message that an account was created for our username,', 'start': 1880.444, 'duration': 7.385}], 'summary': 'Demonstration of form validation and server restarting process.', 'duration': 64.083, 'max_score': 1823.746, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ1823746.jpg'}, {'end': 1995.967, 'src': 'embed', 'start': 1970.309, 'weight': 3, 'content': [{'end': 1978.435, 'text': 'and then you put a div underneath that with the class of invalid feedback and then put in the error there.', 'start': 1970.309, 'duration': 8.126}, {'end': 1980.036, 'text': "so let's see what this looks like.", 'start': 1978.435, 'duration': 1.601}, {'end': 1991.464, 'text': "so I'm going to go underneath our label here and I'm going to just keep this valid feedback form here and now let's put in one that has errors.", 'start': 1980.036, 'duration': 11.428}, {'end': 1995.967, 'text': "so I'm going to open up a code block here and this is going to be an if statement.", 'start': 1991.464, 'duration': 4.503}], 'summary': 'Demonstrating adding error feedback class and code block for if statement.', 'duration': 25.658, 'max_score': 1970.309, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ1970309.jpg'}, {'end': 2053.86, 'src': 'embed', 'start': 2023.235, 'weight': 5, 'content': [{'end': 2036.594, 'text': 'and underneath that invalid field we also want to give a div with a class equal to invalid-feedback And now, within this div,', 'start': 2023.235, 'duration': 13.359}, {'end': 2039.475, 'text': 'we want to print out all of the errors that we have.', 'start': 2036.594, 'duration': 2.881}, {'end': 2043.856, 'text': "So I'll open up another code block here, and this is going to be a for loop.", 'start': 2039.815, 'duration': 4.041}, {'end': 2049.639, 'text': "So we'll say for errors in, and fix that typo there.", 'start': 2044.177, 'duration': 5.462}, {'end': 2053.86, 'text': "So we're going to say for errors in form.username.errors.", 'start': 2049.659, 'duration': 4.201}], 'summary': 'Add div with class invalid-feedback to print form errors.', 'duration': 30.625, 'max_score': 2023.235, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ2023235.jpg'}], 'start': 1570.217, 'title': 'Form validation and user feedback', 'summary': 'Covers the use of flash messages for successes and warnings, the redirect function, and displaying flashed messages in a layout template. additionally, it demonstrates setting up form validation, including validating email and password fields, and providing feedback to the user.', 'chapters': [{'end': 1834.95, 'start': 1570.217, 'title': 'Flask flash messages and redirect', 'summary': 'Covers the use of flash messages for successes and warnings, the redirect function, and displaying flashed messages in a layout template, aiming to enhance user experience and visual feedback.', 'duration': 264.733, 'highlights': ["The chapter demonstrates the use of flash messages with different alert styles for successes and warnings, with the example of passing the name 'success' as a second argument to the flash function. The transcript explains the use of flash messages with different alert styles for successes and warnings, such as passing in the name 'success' as a second argument to the flash function.", 'The chapter explains the use of the redirect function to direct the user to a different page, specifically redirecting to the home page after form submission. It details the use of the redirect function to direct the user to a different page, specifically redirecting to the home page after form submission to avoid confusion.', 'The transcript outlines the process of displaying flashed messages in a layout template for visual feedback, utilizing the get_flashed_messages function and employing conditions for message display. It outlines the process of displaying flashed messages in a layout template, utilizing the get_flashed_messages function and employing conditions for message display to enhance visual feedback.']}, {'end': 2210.438, 'start': 1835.29, 'title': 'Validating form and providing user feedback', 'summary': 'Demonstrates setting up form validation, including validating email and password fields, and providing feedback to the user, with an emphasis on ensuring error messages are displayed for invalid form fields.', 'duration': 375.148, 'highlights': ['Demonstrates validating form fields and providing feedback to the user, emphasizing the importance of displaying error messages for invalid form fields. Importance of displaying error messages, validating form fields, providing feedback to the user.', "Illustrates the process of adding a class of 'is invalid' to the field and including a div with the class 'invalid feedback' to display errors for invalid fields. Adding classes to fields, including div with error messages, displaying errors for invalid fields.", 'Explains the process of using conditional statements and for loops to print out validation errors for the form fields, with examples provided for the username, email, password, and confirm password fields. Using conditional statements and for loops to print validation errors, examples provided for multiple form fields.']}], 'duration': 640.221, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ1570217.jpg', 'highlights': ["The chapter demonstrates the use of flash messages with different alert styles for successes and warnings, such as passing in the name 'success' as a second argument to the flash function.", 'The chapter explains the use of the redirect function to direct the user to a different page, specifically redirecting to the home page after form submission to avoid confusion.', 'The transcript outlines the process of displaying flashed messages in a layout template, utilizing the get_flashed_messages function and employing conditions for message display to enhance visual feedback.', 'Demonstrates validating form fields and providing feedback to the user, emphasizing the importance of displaying error messages for invalid form fields.', "Illustrates the process of adding a class of 'is invalid' to the field and including a div with the class 'invalid feedback' to display errors for invalid fields.", 'Explains the process of using conditional statements and for loops to print out validation errors for the form fields, with examples provided for the username, email, password, and confirm password fields.']}, {'end': 2883.588, 'segs': [{'end': 2259.083, 'src': 'embed', 'start': 2233.887, 'weight': 0, 'content': [{'end': 2241.29, 'text': 'so if i just submit this form, then we can see that we get the feel, the feedback on every single field that says that this field is required,', 'start': 2233.887, 'duration': 7.403}, {'end': 2244.152, 'text': "And it's those bootstrap classes that we added in.", 'start': 2241.63, 'duration': 2.522}, {'end': 2249.416, 'text': 'that handles the coloring of the red text and the red outline on the actual field there.', 'start': 2244.152, 'duration': 5.264}, {'end': 2259.083, 'text': 'So now if I put a username that is too short, remember we said that a username has to be at least two characters, and also an invalid email.', 'start': 2249.736, 'duration': 9.347}], 'summary': 'Form submission provides feedback on required fields and invalid input.', 'duration': 25.196, 'max_score': 2233.887, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ2233887.jpg'}, {'end': 2307.229, 'src': 'embed', 'start': 2270.35, 'weight': 2, 'content': [{'end': 2278.774, 'text': "then we can see now that it's telling us that our field must be between 2 and 20 characters long and that we have an invalid email address,", 'start': 2270.35, 'duration': 8.424}, {'end': 2282.235, 'text': 'and also that this field must be equal to the password.', 'start': 2278.774, 'duration': 3.461}, {'end': 2286.758, 'text': 'and if we had multiple errors on any of these, then it would show all of those as well.', 'start': 2282.235, 'duration': 4.523}, {'end': 2293.902, 'text': "so we're getting some good feedback here to let the user know exactly what they need to fix in order to create their account properly.", 'start': 2286.758, 'duration': 7.144}, {'end': 2298.144, 'text': "okay, so we're almost finished up, but we're also going to do our login page now.", 'start': 2293.902, 'duration': 4.242}, {'end': 2303.147, 'text': "this is going to be a lot faster, because we've already done most of this work for the register page.", 'start': 2298.144, 'duration': 5.003}, {'end': 2307.229, 'text': "so let's copy our register template to our login template.", 'start': 2303.147, 'duration': 4.082}], 'summary': 'Validating fields for user account creation, preparing for login page.', 'duration': 36.879, 'max_score': 2270.35, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ2270350.jpg'}, {'end': 2540.795, 'src': 'embed', 'start': 2504.64, 'weight': 4, 'content': [{'end': 2506.161, 'text': 'Okay, so this is looking pretty good.', 'start': 2504.64, 'duration': 1.521}, {'end': 2514.163, 'text': "Now we don't currently have any users, but let's put some temporary code in here to simulate a successful login.", 'start': 2506.761, 'duration': 7.402}, {'end': 2519.945, 'text': "So I'm going to go back to our application code and go down to our login route.", 'start': 2514.423, 'duration': 5.522}, {'end': 2525.247, 'text': 'And we also want to see if this form is valid on submission as well.', 'start': 2520.465, 'duration': 4.782}, {'end': 2528.669, 'text': "So we'll copy this conditional here and paste this in.", 'start': 2525.628, 'duration': 3.041}, {'end': 2532.811, 'text': 'Now that means that we also need to accept post requests to this route as well.', 'start': 2528.989, 'duration': 3.822}, {'end': 2540.795, 'text': "So just like we did with our register route, let's copy this section that allows post requests to our login route.", 'start': 2533.151, 'duration': 7.644}], 'summary': 'Developing code to simulate successful login and validate form submission.', 'duration': 36.155, 'max_score': 2504.64, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ2504640.jpg'}, {'end': 2784.97, 'src': 'embed', 'start': 2757.11, 'weight': 5, 'content': [{'end': 2762.954, 'text': 'And you definitely want to utilize that function a lot because it makes linking to different pages pretty effortless.', 'start': 2757.11, 'duration': 5.844}, {'end': 2769.799, 'text': "So the only reason I didn't do this in the last video is because our login and register routes didn't exist yet.", 'start': 2763.354, 'duration': 6.445}, {'end': 2774.201, 'text': 'And using URL4 to a non-existent route will throw an error.', 'start': 2770.179, 'duration': 4.022}, {'end': 2778.624, 'text': "So let's see what this looks like to convert existing links to use that URL4 function.", 'start': 2774.502, 'duration': 4.122}, {'end': 2784.97, 'text': "So let's go back to our project and open up our layout template.", 'start': 2779.745, 'duration': 5.225}], 'summary': 'Utilize url4 function for linking to different pages to ensure effortless navigation.', 'duration': 27.86, 'max_score': 2757.11, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ2757110.jpg'}], 'start': 2210.818, 'title': 'Form validation and flask forms', 'summary': 'Demonstrates form validation with zero information submission and feedback for each required field, along with the use of bootstrap classes for styling. it also discusses the implementation of form validation, creation of a login page, use of url4 function for navigation links in flask, and simulating a successful login. additionally, it provides a preview of upcoming topics on database usage and user support.', 'chapters': [{'end': 2249.416, 'start': 2210.818, 'title': 'Form validation and feedback', 'summary': 'Demonstrates form validation by submitting a form with zero information, resulting in feedback for each required field and the use of bootstrap classes for styling.', 'duration': 38.598, 'highlights': ['The form validation provides feedback for each required field, ensuring a user-friendly experience.', 'Bootstrap classes are used to handle the coloring of the red text and outline for the required fields, enhancing the visual presentation.']}, {'end': 2883.588, 'start': 2249.736, 'title': 'Flask forms and login page', 'summary': 'Discusses the implementation of form validation, creation of a login page, and use of url4 function for navigation links in flask, along with simulating a successful login and a preview of upcoming topics on database usage and user support.', 'duration': 633.852, 'highlights': ['The implementation of form validation and feedback to the user is demonstrated, ensuring that the username is at least two characters long and providing an error message for an invalid email address and mismatched passwords. The system provides feedback to the user, indicating that the username must be between 2 and 20 characters long, and highlights an invalid email address and password mismatch to assist the user in creating their account properly.', "Creation of a login page by modifying the register template, removing unnecessary fields, and adding a 'remember me' checkbox along with links for password reset and account registration. The login page is created by modifying the register template, removing unnecessary fields, adding a 'remember me' checkbox, and incorporating links for password reset and account registration, resulting in a streamlined and user-friendly interface.", 'Simulating a successful login process is demonstrated by introducing temporary code, validating the form data, and displaying appropriate messages for successful and unsuccessful login attempts. The process involves simulating a successful login by validating the form data, displaying a success message for the correct email and password combination, and displaying a red alert for invalid login attempts, thus providing a preview of the upcoming database usage.', "Implementation of the URL4 function for navigation links, ensuring automatic updating of routes and effortless linking to different pages. The utilization of the URL4 function for navigation links ensures automatic updating of routes and effortless linking to different pages, enhancing the website's adaptability and user experience."]}], 'duration': 672.77, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/UIJKdCIEXUQ/pics/UIJKdCIEXUQ2210818.jpg', 'highlights': ['The form validation provides feedback for each required field, ensuring a user-friendly experience.', 'Bootstrap classes are used to handle the coloring of the red text and outline for the required fields, enhancing the visual presentation.', 'The implementation of form validation and feedback to the user is demonstrated, ensuring that the username is at least two characters long and providing an error message for an invalid email address and mismatched passwords.', "Creation of a login page by modifying the register template, removing unnecessary fields, and adding a 'remember me' checkbox along with links for password reset and account registration.", 'Simulating a successful login process is demonstrated by introducing temporary code, validating the form data, and displaying appropriate messages for successful and unsuccessful login attempts.', 'Implementation of the URL4 function for navigation links, ensuring automatic updating of routes and effortless linking to different pages.']}], 'highlights': ["The chapter covers adding a link to the login page using an anchor tag with a class of 'margin-left-2' and an href attribute linking to the login page using the URL_for function.", 'The chapter explains the use of the redirect function to direct the user to a different page, specifically redirecting to the home page after form submission to avoid confusion.', "The chapter demonstrates the use of flash messages with different alert styles for successes and warnings, such as passing in the name 'success' as a second argument to the flash function.", "The chapter emphasizes the need to add allowed methods (GET and POST) to the route in order to handle form submission, resolving the 'method not allowed' error.", 'The chapter explains how to add form fields and apply HTML and CSS classes to enhance the styling, with a focus on using bootstrap to improve the appearance of the form.', 'The chapter discusses using the popular wt forms extension for working with forms in flask Highlights the focus of the chapter and the primary tool being used for form handling.', 'The form validation provides feedback for each required field, ensuring a user-friendly experience.', 'The implementation of form validation and feedback to the user is demonstrated, ensuring that the username is at least two characters long and providing an error message for an invalid email address and mismatched passwords.', 'Explains the process of using conditional statements and for loops to print out validation errors for the form fields, with examples provided for the username, email, password, and confirm password fields.', 'The chapter also mentions the use of F strings for formatting messages in Python 3.6 and above, highlighting the benefits of using the latest Python version.']}