title
Flask Course - Python Web Application Development
description
Learn the Flask Python web framework by building your own e-commerce website with its own authentication system.
💻 Full code: https://github.com/jimdevops19/FlaskSeries
💻 Get code snippets used in the course: http://www.jimshapedcoding.com/courses/Flask%20Full%20Series
✏️ Course created by Jim from JimShapedCoding. Check out his channel: https://www.youtube.com/channel/UCU8d7rcShA7MGuDyYH1aWGg
⭐️ Course Contents ⭐️
⌨️ P1 (0:00:00) Introduction
⌨️ P2 (0:20:37) Styling & Templates
⌨️ P3 (0:41:37) Sending data to Templates
⌨️ P4 (1:02:56) Template Inheritance
⌨️ P5 (1:21:14) Models and Databases
⌨️ P6 (1:51:13) Project Restructure
⌨️ P7 (2:05:41) Model Relationships
⌨️ P8 (2:25:37) Flask Forms
⌨️ P9 (2:51:58) Flask Validations
⌨️ P10 (3:14:05) Flashes & Advanced Validations
⌨️ P11 (3:41:04) User Authentication Part 1
⌨️ P12 (3:59:56) User Authentication Part 2
⌨️ P13 (4:34:16) Logout and Customizations
⌨️ P14 (4:51:25) Item Purchasing Part 1
⌨️ P15 (5:18:39) Item Purchasing Part 2
⌨️ P16 (5:54:13) Item Selling
Useful Links:
🔗 Python Download - https://www.python.org/downloads/
🔗 Pycharm Download - https://www.jetbrains.com/pycharm/download/
🔗 Flask Starter Template - https://flask.palletsprojects.com/en/1.1.x/quickstart/
--
Learn to code for free and get a developer job: https://www.freecodecamp.org
Read hundreds of articles on programming: https://freecodecamp.org/news
detail
{'title': 'Flask Course - Python Web Application Development', 'heatmap': [{'end': 4804.239, 'start': 4568.794, 'weight': 0.748}, {'end': 5950.879, 'start': 5715.463, 'weight': 1}, {'end': 6634.277, 'start': 6171.278, 'weight': 0.83}, {'end': 7550.399, 'start': 6855.789, 'weight': 0.722}, {'end': 8688.665, 'start': 7999.069, 'weight': 0.773}], 'summary': 'This flask course covers web development fundamentals, setting up python environment, implementing web features, database configuration, secure registration forms, flashing messages, user authentication, user experience enhancements, market page display, user budget reduction, and html implementation with bootstrap, aiming to develop a marketing system website and e-commerce platform with a budget of 15 grand for real-time transactions.', 'chapters': [{'end': 182.344, 'segs': [{'end': 182.344, 'src': 'embed', 'start': 84.449, 'weight': 0, 'content': [{'end': 90.493, 'text': 'And once I click on create account, then we can see that we receive several errors regarding to that website.', 'start': 84.449, 'duration': 6.044}, {'end': 96.497, 'text': 'So as you can understand, we are going to apply a lot of error handling, like in real websites.', 'start': 90.853, 'duration': 5.644}, {'end': 99.859, 'text': 'So now I will go ahead and create a valid account here.', 'start': 96.917, 'duration': 2.942}, {'end': 106.705, 'text': 'So once I click on create account, then we can see that we are inside a real looking web page.', 'start': 100.379, 'duration': 6.326}, {'end': 116.234, 'text': 'And you can see on the left pane that we have the available items on market and each item has its name and also its barcode and price.', 'start': 107.226, 'duration': 9.008}, {'end': 120.479, 'text': 'And we can display more information about each of our products.', 'start': 116.435, 'duration': 4.044}, {'end': 127.503, 'text': 'And as you can see in up top here, we have our budget that is set by default to 15 grand.', 'start': 121.059, 'duration': 6.444}, {'end': 132.565, 'text': 'So that means that we are going to create a budget system for our users as well.', 'start': 127.883, 'duration': 4.682}, {'end': 139.389, 'text': 'And if I go ahead and purchase that item, which its price is $520.', 'start': 133.086, 'duration': 6.303}, {'end': 149.675, 'text': 'then you can see that we receive a nice message with the purchase item and we can also pay attention that our budget has been changed over here.', 'start': 139.389, 'duration': 10.286}, {'end': 159.18, 'text': 'and further than that, we can see in the right pane that now, on my items, I see that we have a new item, that we have the option to sell it.', 'start': 149.675, 'duration': 9.505}, {'end': 167.228, 'text': "So if I'm going ahead and sell this item back to the market, then we can see that our budget is back at 15 grand.", 'start': 159.58, 'duration': 7.648}, {'end': 173.915, 'text': 'And we can also see that this page is refreshed to what it was before I purchased that item.', 'start': 167.589, 'duration': 6.326}, {'end': 176.939, 'text': 'So it is going to be a lot of fun building this website.', 'start': 174.296, 'duration': 2.643}, {'end': 178.881, 'text': "And let's go ahead and get started.", 'start': 177.319, 'duration': 1.562}, {'end': 182.344, 'text': 'All right, everyone.', 'start': 181.744, 'duration': 0.6}], 'summary': 'Creating a website with error handling, budget system, and item purchasing and selling functionalities.', 'duration': 97.895, 'max_score': 84.449, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo84449.jpg'}], 'start': 0.049, 'title': 'Web development fundamentals', 'summary': 'Covers learning flask web framework for developing a marketing system website, error handling in web page creation, and an e-commerce platform with a budget of 15 grand for real-time transactions.', 'chapters': [{'end': 64.215, 'start': 0.049, 'title': 'Learning flask web framework', 'summary': 'Introduces the flask web framework, emphasizing its ease of use with few lines of code, and outlines the goal to progress from a minimal to an advanced website for a marketing system where users can buy or sell items.', 'duration': 64.166, 'highlights': ['Flask allows everyone to build web applications with only a few lines of code, making website building quicker and easier.', 'The series aims to progress from a minimal application to an advanced website for a marketing system where users can buy or sell items.', 'The main idea of the website is to create a marketing system where different users can buy or sell their items.']}, {'end': 106.705, 'start': 64.556, 'title': 'Error handling in web page creation', 'summary': 'Illustrates the process of error handling in web page creation, including encountering warning messages, mismatching details to observe error handling, and successfully creating a valid account with real-looking web page.', 'duration': 42.149, 'highlights': ['Encountering warning message when accessing a page without logging in', 'Demonstrating error handling by intentionally mismatching details and observing errors', 'Creating a valid account and accessing a real-looking web page']}, {'end': 182.344, 'start': 107.226, 'title': 'E-commerce budget system', 'summary': 'Introduces an e-commerce platform with a budget of 15 grand, where users can view, purchase, sell items and observe the real-time budget updates.', 'duration': 75.118, 'highlights': ['The platform displays available items with name, barcode, and price, and introduces a budget system set at 15 grand.', "Purchasing an item for $520 updates the budget and adds the item to 'My Items', while selling it restores the budget to 15 grand and refreshes the page.", "The system is designed to provide real-time updates on the user's budget and available items, creating an engaging e-commerce experience."]}], 'duration': 182.295, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo49.jpg', 'highlights': ['Flask allows quick and easy web application development with minimal code.', 'The series progresses from a minimal application to an advanced marketing system website.', 'The website aims to create a marketing system for buying and selling items.', 'Demonstrating error handling by intentionally mismatching details and observing errors.', 'The platform displays available items with name, barcode, and price, and introduces a budget system set at 15 grand.', "The system provides real-time updates on the user's budget and available items for an engaging e-commerce experience."]}, {'end': 2421.246, 'segs': [{'end': 221.193, 'src': 'embed', 'start': 199.475, 'weight': 2, 'content': [{'end': 207.84, 'text': "I'm going to assume that you have Python 3.8 or any version above installed and also a ready IDE installed that you work with.", 'start': 199.475, 'duration': 8.365}, {'end': 211.123, 'text': 'So it could be visual code, sublime text, or PyCharm.', 'start': 208.16, 'duration': 2.963}, {'end': 218.25, 'text': "And just to mention off, I'm going to use PyCharm in this series, but it is not quite important which ID you are working with.", 'start': 211.483, 'duration': 6.767}, {'end': 221.193, 'text': 'Just make sure that it is configured with Python correctly.', 'start': 218.43, 'duration': 2.763}], 'summary': 'Assuming python 3.8 or above, using pycharm for coding series.', 'duration': 21.718, 'max_score': 199.475, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo199475.jpg'}, {'end': 703.825, 'src': 'embed', 'start': 674.959, 'weight': 13, 'content': [{'end': 682.325, 'text': 'because we were able to complete the entire starting process successfully in the flask web framework.', 'start': 674.959, 'duration': 7.366}, {'end': 685.868, 'text': 'so we can basically go ahead and continue from here.', 'start': 682.325, 'duration': 3.543}, {'end': 689.871, 'text': 'and one more point that i did not mention you see this hello world text,', 'start': 685.868, 'duration': 4.003}, {'end': 697.237, 'text': 'because this is the root url of your web application and basically the hello world function that we saw before knows how to handle this.', 'start': 689.871, 'duration': 7.366}, {'end': 703.825, 'text': 'So, for example, if I was to go here and type in slash about, for example,', 'start': 697.637, 'duration': 6.188}], 'summary': 'Successfully completed starting process in flask web framework.', 'duration': 28.866, 'max_score': 674.959, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo674959.jpg'}, {'end': 1239.961, 'src': 'embed', 'start': 1189.481, 'weight': 0, 'content': [{'end': 1192.142, 'text': 'So I will go here and type in username.', 'start': 1189.481, 'duration': 2.661}, {'end': 1195.525, 'text': 'And now I can basically go back to our web browser.', 'start': 1192.503, 'duration': 3.022}, {'end': 1198.906, 'text': 'and check out if this works properly.', 'start': 1196.065, 'duration': 2.841}, {'end': 1201.667, 'text': 'So I will go back to our web browser again.', 'start': 1199.066, 'duration': 2.601}, {'end': 1207.649, 'text': "And I will type in here forward slash and then let's give a random name like john.", 'start': 1202.187, 'duration': 5.462}, {'end': 1211.17, 'text': 'And then you can see that we receive a page.', 'start': 1208.069, 'duration': 3.101}, {'end': 1214.911, 'text': 'So we see the message here of this is the about page of john.', 'start': 1211.55, 'duration': 3.361}, {'end': 1218.572, 'text': 'And I could go here and change this to whatever I want.', 'start': 1215.371, 'duration': 3.201}, {'end': 1224.06, 'text': "I can change it to Michael, to Jim and to more names if I'd like to.", 'start': 1219.012, 'duration': 5.048}, {'end': 1230.229, 'text': 'So the important point here is to understand the behavior of dynamic routes.', 'start': 1224.461, 'duration': 5.768}, {'end': 1233.955, 'text': 'So just make sure that you understand the behavior of that as well.', 'start': 1230.51, 'duration': 3.445}, {'end': 1239.961, 'text': 'Okay, so, as you could notice here,', 'start': 1237.398, 'duration': 2.563}], 'summary': 'Demonstrating dynamic routes with multiple name changes.', 'duration': 50.48, 'max_score': 1189.481, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo1189481.jpg'}, {'end': 1930.491, 'src': 'embed', 'start': 1902.725, 'weight': 5, 'content': [{'end': 1910.213, 'text': "So as I said before, I really want to keep on decreasing my explanations about each of the HTML lines that I'm going to write in.", 'start': 1902.725, 'duration': 7.488}, {'end': 1914.657, 'text': 'So we will have a better focus on the Python side of this Flask application.', 'start': 1910.613, 'duration': 4.044}, {'end': 1923.086, 'text': 'But for sure, if you have any questions about the HTML in general, make sure to comment them out so I can read them off and respond to you.', 'start': 1914.998, 'duration': 8.088}, {'end': 1930.491, 'text': "All right, so let's go back to our market.py and take care of something that is quite bothering me until now.", 'start': 1923.226, 'duration': 7.265}], 'summary': 'Focus on python in flask app, open to html questions.', 'duration': 27.766, 'max_score': 1902.725, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo1902725.jpg'}, {'end': 2150.977, 'src': 'embed', 'start': 2122.4, 'weight': 7, 'content': [{'end': 2127.546, 'text': 'And then you can see that we have this nice navigation bar up top here.', 'start': 2122.4, 'duration': 5.146}, {'end': 2133.813, 'text': 'And then you can see that we have its name, which is called Jim shade coding market.', 'start': 2127.706, 'duration': 6.107}, {'end': 2136.568, 'text': 'Now we can change this, whatever text we want.', 'start': 2134.187, 'duration': 2.381}, {'end': 2143.593, 'text': 'We just need to find this specific HTML tag that is responsible to display this text.', 'start': 2136.649, 'duration': 6.944}, {'end': 2150.977, 'text': "So let's actually go ahead and find it so we can have a better practice of how we can find specific HTML tags.", 'start': 2143.953, 'duration': 7.024}], 'summary': 'Tutorial on finding and modifying html tags for navigation bar.', 'duration': 28.577, 'max_score': 2122.4, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo2122400.jpg'}, {'end': 2322.026, 'src': 'embed', 'start': 2279.019, 'weight': 12, 'content': [{'end': 2289.901, 'text': 'so we have here this which is basically a link to our home, and we have that one which is going to be the link for the market in the future, and,', 'start': 2279.019, 'duration': 10.882}, {'end': 2297.283, 'text': 'as you could pay attention, we have in the right side the login and register which we will configure in the future as well.', 'start': 2289.901, 'duration': 7.382}, {'end': 2305.01, 'text': 'Okay so, one more customization that I want to apply for this homepage is to return it into a dark mode.', 'start': 2297.623, 'duration': 7.387}, {'end': 2313.077, 'text': 'Now, in order to allow the page to be in dark mode, basically, you have to override some styling attributes,', 'start': 2305.43, 'duration': 7.647}, {'end': 2322.026, 'text': 'and then your page will be displayed in a background color of black and all the texts that you are going to provide are going to be displayed as white colors.', 'start': 2313.077, 'duration': 8.949}], 'summary': 'Configuring home and market links, login/register setup, and implementing dark mode for homepage.', 'duration': 43.007, 'max_score': 2279.019, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo2279019.jpg'}, {'end': 2402.146, 'src': 'embed', 'start': 2371.461, 'weight': 8, 'content': [{'end': 2374.083, 'text': "And I'm going to add here a colon sign as well.", 'start': 2371.461, 'duration': 2.622}, {'end': 2381.528, 'text': 'And this will be equal to a hexadecimal value that I already know that it is going to display a back color.', 'start': 2374.563, 'duration': 6.965}, {'end': 2390.614, 'text': "So if you don't know what a hexadecimal value is, it is basically another way to define colors rather than just text.", 'start': 2381.908, 'duration': 8.706}, {'end': 2396.04, 'text': 'So this is pretty much equal to writing here black inside a string.', 'start': 2391.195, 'duration': 4.845}, {'end': 2402.146, 'text': 'But this is going to make it a little bit more close to gray rather than just black.', 'start': 2396.44, 'duration': 5.706}], 'summary': 'Using hexadecimal values to define colors in coding.', 'duration': 30.685, 'max_score': 2371.461, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo2371461.jpg'}], 'start': 182.424, 'title': 'Setting up python environment, flask application, and flask web framework basics', 'summary': 'Covers setting up python environment in windows, mac, or linux, setting up a flask application, and explains the basics of flask web framework, including defining routes, handling environment variables, and setting up debug mode, with emphasis on the importance of proper python configuration, project organization, and web page design.', 'chapters': [{'end': 221.193, 'start': 182.424, 'title': 'Setting up python environment', 'summary': 'Covers setting up python environment in windows, mac, or linux, assuming python 3.8 or above and an ide like visual studio code, sublime text, or pycharm, with emphasis on the importance of proper python configuration.', 'duration': 38.769, 'highlights': ['Emphasis on the importance of proper Python configuration, regardless of the IDE being used.', 'Assuming Python 3.8 or any version above installed, along with an IDE like Visual Studio Code, Sublime Text, or PyCharm.', 'The command provided for setting up the environment works on Windows, Mac, and Linux distributions.']}, {'end': 472.946, 'start': 221.753, 'title': 'Setting up flask application', 'summary': 'Illustrates the process of setting up a flask application by creating a directory, installing dependencies using pip, and initializing the flask instance with a basic structure for building the first hello world application in python.', 'duration': 251.193, 'highlights': ['Creating a directory and installing dependencies The speaker demonstrates the process of creating a directory for project files and installing dependencies using pip, emphasizing the installation of Flask for the application.', 'Initializing the Flask instance and importing the flask package The process of initializing the Flask instance with the __name__ argument and importing the flask package is explained, clarifying the purpose of the __name__ variable as a reference to the local Python file.', 'Using the decorator in Python The concept of a decorator in Python is introduced, highlighting its role as a step before a function is executed within the Flask application.']}, {'end': 1239.961, 'start': 473.346, 'title': 'Flask web framework basics', 'summary': 'Explains the basics of flask web framework, including defining routes, handling environment variables, setting up debug mode, and using dynamic routes for customizable web pages.', 'duration': 766.615, 'highlights': ['Flask routes determine the URLs in the website and the corresponding HTML code; the root URL leads to the homepage, and functions defined in routes are called views. Flask routes define the URLs in the website and the corresponding HTML code, with the root URL leading to the homepage. Functions defined in routes are referred to as views.', "Setting up environment variables like 'FLASK_APP' and using 'flask run' command enables the execution of the Flask application, with the default port being 5000. Setting up environment variables such as 'FLASK_APP' and executing the Flask application using 'flask run' enables the application to run, with the default port being 5000.", "Debug mode in Flask synchronizes code changes without requiring server restarts, with 'flask run' command in debug mode allowing real-time code updates. Debug mode in Flask synchronizes code changes without requiring server restarts, enabling real-time code updates using 'flask run' command in debug mode.", 'Dynamic routes in Flask allow the acceptance of variable inputs in URLs, enabling the creation of customizable web pages based on the received variables. Dynamic routes in Flask enable the acceptance of variable inputs in URLs, allowing the creation of customizable web pages based on the received variables.']}, {'end': 1974.247, 'start': 1239.961, 'title': 'Organizing html files in flask', 'summary': 'Explains how to organize html files in flask by creating a templates directory, referring routes to html files, and importing bootstrap for styling, emphasizing the importance of organizing projects and minimizing explanations about html to focus on the python side of the application.', 'duration': 734.286, 'highlights': ['The chapter explains how to organize HTML files in Flask by creating a templates directory, referring routes to HTML files, and importing Bootstrap for styling, emphasizing the importance of organizing projects.', "The convention in Flask is to create a 'templates' directory to store HTML files, and then refer routes to these HTML files, providing a clear structure for the project to enhance organization and maintenance.", 'The tutorial demonstrates the process of referring a route to an HTML file, showcasing the use of render_template function and importing built-in functions from the Flask package.', 'The importance of using a ready styling framework like Bootstrap is highlighted to save time on styling HTML elements, allowing a focus on the Python side of the web application, and emphasizing the significance of using the same version of Bootstrap for consistency.', 'The structure of a basic HTML file is explained, covering the head and body tags, meta information, imports, tab name changes, and the role of JavaScript libraries, with an emphasis on minimizing detailed explanations about HTML to prioritize the Python side of the Flask application.']}, {'end': 2421.246, 'start': 1974.748, 'title': 'Designing nicer web pages', 'summary': 'Covers adding a navigation bar to the homepage, copying html code snippets, customizing the navigation bar, and implementing dark mode for the webpage.', 'duration': 446.498, 'highlights': ['Adding a navigation bar to the homepage The tutorial demonstrates adding a navigation bar to the homepage, allowing users to navigate through different pages.', 'Copying HTML code snippets for faster HTML writing The speaker mentions copying HTML code snippets from a personal website to expedite HTML writing during the tutorial.', 'Customizing the navigation bar The tutorial illustrates customizing the navigation bar by adding extra links for navigation and explains the structure of the code snippets for the navigation bar.', 'Implementing dark mode for the webpage The tutorial covers overriding styling attributes to implement a dark mode for the webpage, with the background color set to black and the text color set to white.']}], 'duration': 2238.822, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo182424.jpg', 'highlights': ['The command provided for setting up the environment works on Windows, Mac, and Linux distributions.', 'Assuming Python 3.8 or any version above installed, along with an IDE like Visual Studio Code, Sublime Text, or PyCharm.', 'Emphasis on the importance of proper Python configuration, regardless of the IDE being used.', 'Creating a directory for project files and installing dependencies using pip, emphasizing the installation of Flask for the application.', 'Initializing the Flask instance with the __name__ argument and importing the flask package is explained, clarifying the purpose of the __name__ variable as a reference to the local Python file.', 'Flask routes determine the URLs in the website and the corresponding HTML code; the root URL leads to the homepage, and functions defined in routes are called views.', "Setting up environment variables such as 'FLASK_APP' and executing the Flask application using 'flask run' enables the application to run, with the default port being 5000.", "Debug mode in Flask synchronizes code changes without requiring server restarts, enabling real-time code updates using 'flask run' command in debug mode.", 'Dynamic routes in Flask enable the acceptance of variable inputs in URLs, allowing the creation of customizable web pages based on the received variables.', 'The chapter explains how to organize HTML files in Flask by creating a templates directory, referring routes to HTML files, and importing Bootstrap for styling, emphasizing the importance of organizing projects.', "The convention in Flask is to create a 'templates' directory to store HTML files, and then refer routes to these HTML files, providing a clear structure for the project to enhance organization and maintenance.", 'The importance of using a ready styling framework like Bootstrap is highlighted to save time on styling HTML elements, allowing a focus on the Python side of the web application, and emphasizing the significance of using the same version of Bootstrap for consistency.', 'Adding a navigation bar to the homepage, allowing users to navigate through different pages.', 'Copying HTML code snippets from a personal website to expedite HTML writing during the tutorial.', 'Customizing the navigation bar by adding extra links for navigation and explaining the structure of the code snippets for the navigation bar.', 'Implementing dark mode for the webpage by overriding styling attributes to set the background color to black and the text color to white.']}, {'end': 3739.079, 'segs': [{'end': 2654.873, 'src': 'embed', 'start': 2606.167, 'weight': 0, 'content': [{'end': 2608.249, 'text': "And let's make the font a little bit bigger here.", 'start': 2606.167, 'duration': 2.082}, {'end': 2616.854, 'text': 'Now several changes that it might be a great idea to done here is for sure this title tag that is changing the tab name.', 'start': 2608.789, 'duration': 8.065}, {'end': 2622.258, 'text': "So let's change this to market and I will scroll down here.", 'start': 2617.275, 'duration': 4.983}, {'end': 2632.545, 'text': "Let's minimize this nav bar and we will change this homepage H1 tag to market page so we can understand where we are currently at.", 'start': 2622.498, 'duration': 10.047}, {'end': 2636.126, 'text': 'Now for myself here, the website is currently not running.', 'start': 2632.825, 'duration': 3.301}, {'end': 2641.568, 'text': "So let's go ahead and complete the steps that we are required to run our website quickly.", 'start': 2636.386, 'duration': 5.182}, {'end': 2646.43, 'text': 'So set flask app equals to market dot py.', 'start': 2641.988, 'duration': 4.442}, {'end': 2650.831, 'text': 'And we also have to set the flask underscore debug to one.', 'start': 2646.73, 'duration': 4.101}, {'end': 2654.873, 'text': 'And now we are ready to go ahead and execute flask run.', 'start': 2651.312, 'duration': 3.561}], 'summary': 'Making changes to website layout and setting up for execution.', 'duration': 48.706, 'max_score': 2606.167, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo2606167.jpg'}, {'end': 2939.299, 'src': 'embed', 'start': 2907.474, 'weight': 3, 'content': [{'end': 2913.377, 'text': "So let's copy this up and paste this inside our market page.", 'start': 2907.474, 'duration': 5.903}, {'end': 2915.979, 'text': "Now, let's have a quick look in this long list here.", 'start': 2913.477, 'duration': 2.502}, {'end': 2922.702, 'text': 'Basically, what we are having is three dictionaries that they are happening to have the same keys.', 'start': 2916.379, 'duration': 6.323}, {'end': 2930.627, 'text': 'So we have ID for this and this and that and also the name key and as well as barcode and a price.', 'start': 2923.123, 'duration': 7.504}, {'end': 2939.299, 'text': 'Now, once I have copied this out, it might be a better idea to change our send information in this render template.', 'start': 2931.147, 'duration': 8.152}], 'summary': 'Three dictionaries with identical keys for id, name, barcode, and price are being processed.', 'duration': 31.825, 'max_score': 2907.474, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo2907474.jpg'}, {'end': 3110.005, 'src': 'embed', 'start': 3039.676, 'weight': 1, 'content': [{'end': 3048.579, 'text': 'so if we copy this, then we can see that we have here the table tag again, but we have an attribute that we did not talk about it before.', 'start': 3039.676, 'duration': 8.903}, {'end': 3052.8, 'text': 'basically, when you see the class attribute inside an html file,', 'start': 3048.579, 'duration': 4.221}, {'end': 3060.983, 'text': 'it basically refers to bootstrap classes that their main goal is to give a nicer design to your specific html templates.', 'start': 3052.8, 'duration': 8.183}, {'end': 3064.845, 'text': 'So, for example, if we see a class that is named the table hover,', 'start': 3061.383, 'duration': 3.462}, {'end': 3069.668, 'text': 'then we should see a special effect when we bring our mouse and hover inside our table.', 'start': 3064.845, 'duration': 4.823}, {'end': 3075.852, 'text': 'And if we see table dark, then you can probably understand that this table is going to be in dark design.', 'start': 3070.049, 'duration': 5.803}, {'end': 3081.276, 'text': 'So in here, we have our table head and table body.', 'start': 3076.293, 'duration': 4.983}, {'end': 3087.002, 'text': 'And as you can see, I already commented here that we have to create certain columns here.', 'start': 3081.816, 'duration': 5.186}, {'end': 3095.752, 'text': 'Now, since our dictionary includes some more than one key values, then it might be a great idea to create more columns to our table.', 'start': 3087.302, 'duration': 8.45}, {'end': 3098.235, 'text': 'So this is why I will go down here.', 'start': 3096.132, 'duration': 2.103}, {'end': 3103.299, 'text': 'And I will start copying and pasting this code snippet three more times.', 'start': 3098.775, 'duration': 4.524}, {'end': 3110.005, 'text': 'And I will replace those by the values of the keys that we have inside our dictionaries.', 'start': 3103.799, 'duration': 6.206}], 'summary': 'Using bootstrap classes for better html design, adding columns to table.', 'duration': 70.329, 'max_score': 3039.676, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo3039676.jpg'}, {'end': 3402.386, 'src': 'embed', 'start': 3369.023, 'weight': 2, 'content': [{'end': 3383.79, 'text': 'because this is accessible from the market route and to close our for loop here i will call those code blocks once again and i will write here and for together combined.', 'start': 3369.023, 'duration': 14.767}, {'end': 3390.293, 'text': 'so this is the exact syntax of how you can bring in a for loop inside your html template.', 'start': 3383.79, 'duration': 6.503}, {'end': 3396.724, 'text': "And now I'm going to cut this entire TRHTML block here.", 'start': 3390.802, 'duration': 5.922}, {'end': 3402.386, 'text': "And I'm going to paste this in inside this for loop that we have just created.", 'start': 3397.104, 'duration': 5.282}], 'summary': 'Demonstrating the syntax for adding a for loop inside an html template.', 'duration': 33.363, 'max_score': 3369.023, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo3369023.jpg'}], 'start': 2421.706, 'title': 'Implementing web features in flask', 'summary': 'Details implementing dark mode, creating a new route, setting up a flask website, displaying data, iterating over items using jinja templates, and updating the market table to enhance user experience and functionality.', 'chapters': [{'end': 2632.545, 'start': 2421.706, 'title': 'Implementing dark mode and creating a new route', 'summary': 'Details the implementation of dark mode on a website and the creation of a new route, including changing the tab name and creating a market page in python, emphasizing the importance of applying configurations and customizing html files.', 'duration': 210.839, 'highlights': ["The website is turned into dark mode by applying configurations to the home.html file, enhancing the website's appearance. Dark mode implementation, applying configurations", "The tab name of the website is changed from 'hello world' to 'home page' to finalize the styling. Tab name modification, styling completion", "The creation of a new route 'market' and the rendering of a new HTML template 'market.html' is initiated, highlighting the process of directing users to the market page. New route creation, rendering new HTML template", 'Customization of the market page is done by copying and modifying the existing home.html file, emphasizing the importance of differentiating the market page from the homepage. Customization of HTML file, differentiation of market page']}, {'end': 2854.13, 'start': 2632.825, 'title': 'Flask website setup and data display', 'summary': 'Demonstrates the setup of a flask website, including setting up the environment and displaying data on the web page using jinja template, achieving a successful display of the item name variable on the webpage.', 'duration': 221.305, 'highlights': ['The chapter demonstrates the setup of a Flask website, including setting up the environment and displaying data on the web page using Jinja template.', 'The process involves setting flask app equal to market.py, setting flask_debug to 1, and executing flask run.', 'The demonstration includes sending random data from the route to the HTML and accessing it using Jinja template, with a successful display of the item name variable on the webpage.', 'The chapter explains the usage of Jinja template, a special web templating syntax designed for Python web frameworks, enabling the access of information sent from the route through HTML.', 'The demonstration includes a clear explanation of including Jinja syntax in HTML templates and the successful display of the item name variable on the webpage.']}, {'end': 3295.106, 'start': 2854.53, 'title': 'Displaying multiple items in flask', 'summary': "Explains how to display multiple items on a website using flask by sending a list of dictionaries to the template and iterating over the list to create a styled table with the items' details.", 'duration': 440.576, 'highlights': ['Sending a list of dictionaries to the template The chapter explains sending a list of dictionaries to the template to display multiple items on the website.', "Creating a styled table with items' details The chapter demonstrates creating a styled table with the items' details by iterating over the list of dictionaries to display the items' details in a table format.", "Iterating over the list to display items' details The chapter details the process of iterating over the list of dictionaries to display the items' details in a table format on the website."]}, {'end': 3507.924, 'start': 3295.546, 'title': 'Using jinja templates for iteration', 'summary': 'Explains how to use jinja template syntax to iterate over items in a for loop inside an html template, resulting in the table row being displayed for each dictionary in the items list and accessing the keys to display the values, which is demonstrated by iterating over three dictionaries and displaying their values.', 'duration': 212.378, 'highlights': ['The chapter demonstrates using Jinja template syntax to iterate over items in a for loop inside an HTML template, resulting in the table row being displayed for each dictionary in the items list.', 'The instructor explains how to access the keys of the dictionaries to display the values by using the item.variable syntax and demonstrates iterating over three dictionaries and displaying their values.', 'The instructor provides a step-by-step explanation of replacing the strings inside the HTML tags with the actual values of the keys from the dictionary by using the item.variable syntax.']}, {'end': 3739.079, 'start': 3508.364, 'title': 'Updating market table with price and options', 'summary': 'Discusses updating the market table with price, including a dollar sign, and adding options for users to view more information and purchase items, enhancing user experience and functionality.', 'duration': 230.715, 'highlights': ['Adding a dollar sign to the price for clarity, enhancing user understanding and improving user experience.', 'Adding options for users to view more information and purchase items, improving functionality and user experience.', 'Updating the market table with price for automatic updates, ensuring accurate and real-time information display.']}], 'duration': 1317.373, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo2421706.jpg', 'highlights': ['Dark mode implementation, applying configurations', 'New route creation, rendering new HTML template', 'Setting up Flask website, displaying data using Jinja template', 'Sending a list of dictionaries to the template', "Creating a styled table with items' details", "Iterating over the list to display items' details", 'Using Jinja template syntax to iterate over items in a for loop', 'Enhancing user understanding by adding a dollar sign to the price', 'Improving functionality and user experience by adding options for users', 'Updating the market table with price for automatic updates']}, {'end': 4853.111, 'segs': [{'end': 4152.541, 'src': 'embed', 'start': 4121.908, 'weight': 3, 'content': [{'end': 4125.229, 'text': 'And then you can see that we are happen to have this black page.', 'start': 4121.908, 'duration': 3.321}, {'end': 4136.594, 'text': 'So now that we achieve this Basically now we can decide which content we want to put inside base.html and which content we want our inside home.html.', 'start': 4125.41, 'duration': 11.184}, {'end': 4144.778, 'text': 'So for example, our long navigation bar HTML tags are must located inside our base.html.', 'start': 4136.715, 'duration': 8.063}, {'end': 4146.298, 'text': "So let's go ahead and do that.", 'start': 4144.877, 'duration': 1.421}, {'end': 4152.541, 'text': "So I will go to our PyCharm and let's actually bring this long nav tag from the market.html.", 'start': 4146.718, 'duration': 5.823}], 'summary': 'Deciding content placement for base.html and home.html in pycharm.', 'duration': 30.633, 'max_score': 4121.908, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo4121908.jpg'}, {'end': 4804.239, 'src': 'heatmap', 'start': 4568.794, 'weight': 0.748, 'content': [{'end': 4574.619, 'text': 'So I will go in here and then create an indentation a little bit and then paste back our table.', 'start': 4568.794, 'duration': 5.825}, {'end': 4576.021, 'text': 'So I think this should work.', 'start': 4574.82, 'duration': 1.201}, {'end': 4580.965, 'text': "Let's test this out by going to Chrome again, and refresh our homepage.", 'start': 4576.181, 'duration': 4.784}, {'end': 4583.107, 'text': 'And then you can see that the behavior is quite same.', 'start': 4581.045, 'duration': 2.062}, {'end': 4591.053, 'text': 'Now I will navigate also to our market And then you can see that we still get pretty much the same result like we have done previously.', 'start': 4583.588, 'duration': 7.465}, {'end': 4598.778, 'text': 'What we can do is basically adding a title like market page and we will just continue with the customizations in the future.', 'start': 4591.493, 'duration': 7.285}, {'end': 4601.66, 'text': 'So this is a pretty much great results until now.', 'start': 4599.158, 'duration': 2.502}, {'end': 4608.164, 'text': 'And I hope that the entire process of how we can use the template inheritance was pretty much clear for you.', 'start': 4601.82, 'duration': 6.344}, {'end': 4613.987, 'text': 'Okay, so there are still customizations left before we close this template inheritance topic.', 'start': 4608.664, 'duration': 5.323}, {'end': 4621.451, 'text': "And basically, inside our navigation bar, we currently don't have the functionality to navigate between different pages.", 'start': 4614.327, 'duration': 7.124}, {'end': 4625.514, 'text': 'So to test this up, if I click on homepage, nothing happens.', 'start': 4621.972, 'duration': 3.542}, {'end': 4628.375, 'text': 'And as well as in our market over here.', 'start': 4625.934, 'duration': 2.441}, {'end': 4630.476, 'text': "So let's go ahead and configure them.", 'start': 4628.715, 'duration': 1.761}, {'end': 4634.479, 'text': 'So I will open our pie charm again, and we will open our base template.', 'start': 4630.536, 'duration': 3.943}, {'end': 4642.724, 'text': 'And inside our navigation bar, we can basically look up for those a tags.', 'start': 4635.099, 'duration': 7.625}, {'end': 4649.53, 'text': 'Now those a tags are what responsible to navigate users to different pages.', 'start': 4643.145, 'duration': 6.385}, {'end': 4659.277, 'text': 'And so if you look at the href attribute inside the a tags, this is what is actually sending our users to different areas.', 'start': 4650.05, 'duration': 9.227}, {'end': 4663.32, 'text': 'Now, we could have done here something like slash home.', 'start': 4659.737, 'duration': 3.583}, {'end': 4667.323, 'text': 'So in that case, it will navigate our users to slash home.', 'start': 4663.78, 'duration': 3.543}, {'end': 4675.309, 'text': "But this is not a great idea because you don't want to hard code your URLs in that way.", 'start': 4667.983, 'duration': 7.326}, {'end': 4683.455, 'text': 'So what happens if in one day you want to change the route to something else, then it is not considered as a best practice.', 'start': 4675.689, 'duration': 7.766}, {'end': 4685.436, 'text': 'Now again, this is going to work.', 'start': 4683.875, 'duration': 1.561}, {'end': 4687.256, 'text': "I'm not saying that it is not going to work.", 'start': 4685.496, 'duration': 1.76}, {'end': 4688.717, 'text': 'But it is quite wrong.', 'start': 4687.616, 'duration': 1.101}, {'end': 4691.258, 'text': 'And we can even check this out if it works properly.', 'start': 4688.997, 'duration': 2.261}, {'end': 4695.819, 'text': 'So we can go to here and refresh our page and click on home.', 'start': 4691.298, 'duration': 4.521}, {'end': 4698.941, 'text': 'And then this will basically navigate our users to homepage.', 'start': 4696.16, 'duration': 2.781}, {'end': 4701.101, 'text': 'But we can do this in a more pretty way.', 'start': 4699.281, 'duration': 1.82}, {'end': 4702.962, 'text': 'And I like to apply that.', 'start': 4701.542, 'duration': 1.42}, {'end': 4705.243, 'text': "Okay, so I'll open back our Python.", 'start': 4703.062, 'duration': 2.181}, {'end': 4709.264, 'text': 'And in here, besides hard coding for slash home,', 'start': 4705.783, 'duration': 3.481}, {'end': 4716.946, 'text': 'we can basically use a built-in function from the Jinja syntax that is going to look like URL underscore four.', 'start': 4709.264, 'duration': 7.682}, {'end': 4722.508, 'text': "So let's call this up in here and pay attention that I use the double curly brackets.", 'start': 4717.106, 'duration': 5.402}, {'end': 4726.309, 'text': 'So in here, I can close this function like that.', 'start': 4722.988, 'duration': 3.321}, {'end': 4732.191, 'text': 'And between here, the URL underscore four expects for one special argument.', 'start': 4726.789, 'duration': 5.402}, {'end': 4742.476, 'text': 'Now the argument that we are going to give for that function will be the value of the name of our route that we want to navigate our users.', 'start': 4732.671, 'duration': 9.805}, {'end': 4751.6, 'text': 'So in this case, if we want to navigate our users to the homepage, then we should type in here the name of our route.', 'start': 4742.956, 'duration': 8.644}, {'end': 4755.122, 'text': 'that we have created to navigate our users to the homepage.', 'start': 4752.02, 'duration': 3.102}, {'end': 4761.166, 'text': 'And in our case, if you remember, our route name was home underscore page.', 'start': 4755.502, 'duration': 5.664}, {'end': 4766.349, 'text': 'So we can basically go here and type in home underscore page.', 'start': 4761.486, 'duration': 4.863}, {'end': 4770.994, 'text': "And once I save this, Let's go to our web page and test this out.", 'start': 4766.709, 'duration': 4.285}, {'end': 4782.006, 'text': 'So I will basically navigate back to market and I will click on the homepage and then you can see that it knows automatically to navigate our users to forward,', 'start': 4771.134, 'duration': 10.872}, {'end': 4782.807, 'text': 'slash, home.', 'start': 4782.006, 'duration': 0.801}, {'end': 4785.07, 'text': 'Now this would even work.', 'start': 4783.248, 'duration': 1.822}, {'end': 4793.493, 'text': 'If I was to go inside our market.py and change this to something else like home three times.', 'start': 4785.61, 'duration': 7.883}, {'end': 4797.375, 'text': "Okay, let's just do this for testing reasons and test that out.", 'start': 4793.573, 'duration': 3.802}, {'end': 4799.736, 'text': 'So I will go to market again.', 'start': 4797.455, 'duration': 2.281}, {'end': 4804.239, 'text': 'and try to navigate back to our homepage,', 'start': 4800.576, 'duration': 3.663}], 'summary': 'Utilizing template inheritance for navigation customization and testing different page navigation', 'duration': 235.445, 'max_score': 4568.794, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo4568794.jpg'}, {'end': 4621.451, 'src': 'embed', 'start': 4591.493, 'weight': 0, 'content': [{'end': 4598.778, 'text': 'What we can do is basically adding a title like market page and we will just continue with the customizations in the future.', 'start': 4591.493, 'duration': 7.285}, {'end': 4601.66, 'text': 'So this is a pretty much great results until now.', 'start': 4599.158, 'duration': 2.502}, {'end': 4608.164, 'text': 'And I hope that the entire process of how we can use the template inheritance was pretty much clear for you.', 'start': 4601.82, 'duration': 6.344}, {'end': 4613.987, 'text': 'Okay, so there are still customizations left before we close this template inheritance topic.', 'start': 4608.664, 'duration': 5.323}, {'end': 4621.451, 'text': "And basically, inside our navigation bar, we currently don't have the functionality to navigate between different pages.", 'start': 4614.327, 'duration': 7.124}], 'summary': 'Developing a market page with customizations, aiming for clear navigation functionality.', 'duration': 29.958, 'max_score': 4591.493, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo4591493.jpg'}, {'end': 4770.994, 'src': 'embed', 'start': 4742.956, 'weight': 1, 'content': [{'end': 4751.6, 'text': 'So in this case, if we want to navigate our users to the homepage, then we should type in here the name of our route.', 'start': 4742.956, 'duration': 8.644}, {'end': 4755.122, 'text': 'that we have created to navigate our users to the homepage.', 'start': 4752.02, 'duration': 3.102}, {'end': 4761.166, 'text': 'And in our case, if you remember, our route name was home underscore page.', 'start': 4755.502, 'duration': 5.664}, {'end': 4766.349, 'text': 'So we can basically go here and type in home underscore page.', 'start': 4761.486, 'duration': 4.863}, {'end': 4770.994, 'text': "And once I save this, Let's go to our web page and test this out.", 'start': 4766.709, 'duration': 4.285}], 'summary': "To navigate users to the homepage, type 'home_page' as the route name and test on the webpage.", 'duration': 28.038, 'max_score': 4742.956, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo4742956.jpg'}], 'start': 3739.56, 'title': 'Implementing template inheritance in html, python and dynamic navigation', 'summary': 'Explains the concept of template inheritance in html, python, and dynamic navigation, highlighting time-saving and efficient code management, consistent display of navigation bar, and achieving dynamic navigation through url_for function.', 'chapters': [{'end': 4022.812, 'start': 3739.56, 'title': 'Implementing template inheritance in html', 'summary': 'Explains the concept of template inheritance in html, emphasizing the need to avoid repetitive copying of html code and the benefits of creating a base layout template, ultimately leading to time-saving and efficient code management.', 'duration': 283.252, 'highlights': ['The concept of template inheritance is introduced to avoid repetitive copying and pasting of HTML code for creating multiple pages, ultimately saving time and effort. The idea behind template inheritance is to have one base template HTML that will be inherited from, saving a lot of copying and pasting HTML code.', 'Emphasizing the need to avoid repetitive copying and pasting of HTML code for maintaining consistency across multiple pages. The chapter highlights the importance of keeping certain elements in each page to maintain consistency, such as displaying a navigation bar in each page for user navigation.', 'Demonstrating the creation of a base layout template in HTML to serve as a foundation for displaying common elements across multiple pages. The chapter explains the process of creating a base layout template and how it can be used to display common elements across various pages, ultimately streamlining the development process.']}, {'end': 4238.568, 'start': 4022.972, 'title': 'Html template inheritance', 'summary': 'Explores using the extends method to inherit code from a base.html file into home.html, enabling the consistent display of the navigation bar across different html files, leading to a more efficient website development process.', 'duration': 215.596, 'highlights': ['The chapter explains how to use the extends method to inherit code from a base.html file into home.html, ensuring a consistent display of the navigation bar across different HTML files, enhancing the website development process.', 'The speaker demonstrates the process of copying the navigation bar HTML tag from market.html and pasting it into base.html, resulting in the successful display of the navigation bar on the website, highlighting the practical application of the inheritance method.', 'The narrator emphasizes the efficiency of the inheritance process, noting that by using the extends method, the navigation bar will be automatically displayed in all future HTML files, simplifying the development of new pages.']}, {'end': 4613.987, 'start': 4238.849, 'title': 'Template inheritance in python', 'summary': 'Discusses the concept of template inheritance in python, demonstrating how to mark unique per page content using jinja syntax, allowing for organized code and the ability to call these blocks in different pages inside the project.', 'duration': 375.138, 'highlights': ['Demonstrating how to mark unique per page content using Jinja syntax The speaker explains how to mark unique per page content using Jinja syntax, allowing for organized code and demonstrating the practical application of the concept.', 'The ability to call these blocks in different pages inside the project The chapter emphasizes the importance of being able to call these blocks in different pages inside the project, which enhances code reusability and organization.', 'Explaining the concept of template inheritance in Python The speaker explains the concept of template inheritance in Python, providing a foundational understanding of the topic.']}, {'end': 4853.111, 'start': 4614.327, 'title': 'Dynamic navigation implementation', 'summary': 'Discusses the implementation of dynamic navigation using built-in jinja function url_for, avoiding hard-coded urls, and achieving dynamic navigation to different pages by specifying the name of the route, with a test demonstrating the functionality.', 'duration': 238.784, 'highlights': ['The implementation of dynamic navigation using the built-in Jinja function URL_for ensures dynamic navigation to different pages by specifying the name of the route, rather than hard-coding URLs, promoting best practices and flexibility.', 'Avoiding hard-coded URLs in the navigation implementation is emphasized, as it allows for easier maintenance and updates in case of route changes, aligning with best practices and ensuring flexibility.', "The demonstration of the dynamic navigation functionality is showcased through a test, altering the route name from 'home_page' to 'home_home_home' and then reverting it back, proving the flexibility and effectiveness of the implementation."]}], 'duration': 1113.551, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo3739560.jpg', 'highlights': ['The implementation of dynamic navigation using the built-in Jinja function URL_for ensures dynamic navigation to different pages by specifying the name of the route, rather than hard-coding URLs, promoting best practices and flexibility.', 'The concept of template inheritance is introduced to avoid repetitive copying and pasting of HTML code for creating multiple pages, ultimately saving time and effort. The idea behind template inheritance is to have one base template HTML that will be inherited from, saving a lot of copying and pasting HTML code.', 'The chapter explains how to use the extends method to inherit code from a base.html file into home.html, ensuring a consistent display of the navigation bar across different HTML files, enhancing the website development process.', 'Demonstrating how to mark unique per page content using Jinja syntax The speaker explains how to mark unique per page content using Jinja syntax, allowing for organized code and demonstrating the practical application of the concept.']}, {'end': 6422.516, 'segs': [{'end': 4910.873, 'src': 'embed', 'start': 4881.479, 'weight': 8, 'content': [{'end': 4886.741, 'text': 'so if you remember those items that you see on the slash market page,', 'start': 4881.479, 'duration': 5.262}, {'end': 4896.864, 'text': 'was basically because of the list of dictionaries that is arriving from here and is sent directly to our template.', 'start': 4886.741, 'duration': 10.123}, {'end': 4899.986, 'text': 'And now we want to look for a way to change this behavior.', 'start': 4897.044, 'duration': 2.942}, {'end': 4905.049, 'text': 'So we will be able to store information inside an organized database.', 'start': 4900.346, 'duration': 4.703}, {'end': 4910.873, 'text': 'So the way we are going to do that is by configuring several configurations on our flask application.', 'start': 4905.409, 'duration': 5.464}], 'summary': 'Transcript discusses transitioning from using a list of dictionaries to an organized database in flask application.', 'duration': 29.394, 'max_score': 4881.479, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo4881479.jpg'}, {'end': 5019.404, 'src': 'embed', 'start': 4988.983, 'weight': 0, 'content': [{'end': 4994.226, 'text': 'So SQLite tree is an extension of a file that allows to store information.', 'start': 4988.983, 'duration': 5.243}, {'end': 4998.468, 'text': 'And we are going to connect that file to our flask application.', 'start': 4994.546, 'duration': 3.922}, {'end': 4999.929, 'text': "So let's go ahead and do that.", 'start': 4998.548, 'duration': 1.381}, {'end': 5008.755, 'text': 'Okay, so first of first, we need a flask tool that allows to create tables within that database that we are going to work with.', 'start': 5000.209, 'duration': 8.546}, {'end': 5011.177, 'text': 'with using Python code.', 'start': 5009.395, 'duration': 1.782}, {'end': 5019.404, 'text': 'Now when it comes to developing websites with Python, basically you can create your database tables with Python classes.', 'start': 5011.617, 'duration': 7.787}], 'summary': 'Using sqlite tree extension to store information and connect it to a flask application for creating database tables with python classes.', 'duration': 30.421, 'max_score': 4988.983, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo4988983.jpg'}, {'end': 5350.498, 'src': 'embed', 'start': 5295.403, 'weight': 1, 'content': [{'end': 5304.727, 'text': 'Okay, so once I have done that, I can basically go outside of our string class in here and pass in here some more arguments.', 'start': 5295.403, 'duration': 9.324}, {'end': 5305.927, 'text': 'right there.', 'start': 5305.507, 'duration': 0.42}, {'end': 5315.151, 'text': "So one of the first arguments that we want to pass is to describe to that column that we don't want to have null fields.", 'start': 5306.407, 'duration': 8.744}, {'end': 5321.074, 'text': 'So we can go ahead and do that by passing in here nullable equals to false.', 'start': 5315.371, 'duration': 5.703}, {'end': 5331.72, 'text': "And the next argument that I'm going to specify here is going to allow our names to not have the same name when it comes to storing a large amount of items.", 'start': 5321.254, 'duration': 10.466}, {'end': 5340.688, 'text': 'So you probably want to avoid the situation where you have two or more items that their name are iPhone 10, for example.', 'start': 5332.2, 'duration': 8.488}, {'end': 5344.612, 'text': 'So you want each item name to be unique.', 'start': 5341.049, 'duration': 3.563}, {'end': 5350.498, 'text': 'And you can do that by easily saying unique equals to true.', 'start': 5344.752, 'duration': 5.746}], 'summary': 'Pass nullable=false and unique=true arguments to string class.', 'duration': 55.095, 'max_score': 5295.403, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo5295403.jpg'}, {'end': 5456.742, 'src': 'embed', 'start': 5422.996, 'weight': 5, 'content': [{'end': 5425.157, 'text': 'So it will be DB dot column.', 'start': 5422.996, 'duration': 2.161}, {'end': 5435.744, 'text': "And although it is going to contain some digits, I still want to pass it in as strings because I'm not going to do any calculation with this barcode.", 'start': 5425.718, 'duration': 10.026}, {'end': 5440.707, 'text': "I'm just going to store 12 characters that they happen to be digits.", 'start': 5436.144, 'duration': 4.563}, {'end': 5450.656, 'text': 'So I will go in here and create string and we will just pass in here length equals 12, so each barcode will be 12 characters,', 'start': 5440.767, 'duration': 9.889}, {'end': 5456.742, 'text': 'and again we will type in nullable equals false, and this should be unique as well.', 'start': 5450.656, 'duration': 6.086}], 'summary': 'Database column for barcode storing 12 unique digit characters as strings.', 'duration': 33.746, 'max_score': 5422.996, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo5422996.jpg'}, {'end': 5687.06, 'src': 'embed', 'start': 5659.092, 'weight': 6, 'content': [{'end': 5666.674, 'text': 'So I will basically type in here sqlite three colon slash and we should add two more four slashes here as well.', 'start': 5659.092, 'duration': 7.582}, {'end': 5670.255, 'text': 'And once I have done that, we will just give a name to our database file.', 'start': 5666.854, 'duration': 3.401}, {'end': 5673.196, 'text': 'So it will be market dot DB.', 'start': 5670.595, 'duration': 2.601}, {'end': 5676.557, 'text': 'Okay, so I know this line might confuse everyone here.', 'start': 5674.016, 'duration': 2.541}, {'end': 5679.278, 'text': "So let's go ahead step by step to understand this.", 'start': 5676.877, 'duration': 2.401}, {'end': 5687.06, 'text': 'So first of first, we see this app flask equals to double underscore name that we have created in the very first step.', 'start': 5679.418, 'duration': 7.642}], 'summary': 'Setting up a sqlite database file named market.db for a flask app.', 'duration': 27.968, 'max_score': 5659.092, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo5659092.jpg'}, {'end': 5950.879, 'src': 'heatmap', 'start': 5715.463, 'weight': 1, 'content': [{'end': 5716.623, 'text': 'underscore URI.', 'start': 5715.463, 'duration': 1.16}, {'end': 5720.686, 'text': 'So URI stands for Uniform Resource Identifier.', 'start': 5716.824, 'duration': 3.862}, {'end': 5727.29, 'text': 'And this is different from URL that you probably saw everywhere because this is not a link to a website.', 'start': 5721.086, 'duration': 6.204}, {'end': 5730.212, 'text': 'This is why we see the L at the end of this statement.', 'start': 5727.33, 'duration': 2.882}, {'end': 5735.776, 'text': 'This is an identifier that is just a file that is going to be identified as database.', 'start': 5730.672, 'duration': 5.104}, {'end': 5743.822, 'text': 'And basically, the way that Flask application wants us to do it is by passing in here SQL, like the colon three, four slashes,', 'start': 5735.856, 'duration': 7.966}, {'end': 5748.206, 'text': "and then just give a random name to the file that you're going to create.", 'start': 5743.822, 'duration': 4.384}, {'end': 5755.714, 'text': 'Okay, so once we have configured this successfully, then we should go ahead and execute some commands in order to create this actual file.', 'start': 5748.347, 'duration': 7.367}, {'end': 5760.118, 'text': 'And then we can see it visible inside our project directory.', 'start': 5756.094, 'duration': 4.024}, {'end': 5772.226, 'text': 'so i will open our terminal here and inside our command line we want to enter to python shell because we want to import the information from our market.py file.', 'start': 5760.558, 'duration': 11.668}, {'end': 5779.35, 'text': 'so i can basically go ahead and type in here python and make sure that you do that in the same directory as your project,', 'start': 5772.226, 'duration': 7.124}, {'end': 5781.412, 'text': 'so you will not receive any errors.', 'start': 5779.35, 'duration': 2.062}, {'end': 5789.057, 'text': 'So once I have done that, basically I can import our market.py file like a Python module.', 'start': 5781.992, 'duration': 7.065}, {'end': 5791.058, 'text': 'So I will type in here import.', 'start': 5789.157, 'duration': 1.901}, {'end': 5797.623, 'text': 'I mean from market because this is the name of our Python file import.', 'start': 5791.739, 'duration': 5.884}, {'end': 5801.444, 'text': 'db. now the reason i want to import db.', 'start': 5798.263, 'duration': 3.181}, {'end': 5807.886, 'text': 'it is basically because i want to take several actions within that db variable that we created previously.', 'start': 5801.444, 'duration': 6.442}, {'end': 5814.927, 'text': 'now, once i will execute this, you might receive a warning about some of the features that are going to be disabled in the near future.', 'start': 5807.886, 'duration': 7.041}, {'end': 5816.568, 'text': "but don't worry too much about that.", 'start': 5814.927, 'duration': 1.641}, {'end': 5820.929, 'text': 'this is not an error, so you are totally fine if you see this output.', 'start': 5816.568, 'duration': 4.361}, {'end': 5829.856, 'text': 'Now, I want to split our display a little bit just to see you the result of what happens when I run the following command.', 'start': 5821.405, 'duration': 8.451}, {'end': 5835.924, 'text': "So I will basically locate our terminal in here and we'll make it a little bit bigger like that.", 'start': 5829.896, 'duration': 6.028}, {'end': 5839.809, 'text': 'And now I will go ahead and create our database.', 'start': 5836.364, 'duration': 3.445}, {'end': 5850.22, 'text': 'Now, the way that we can do that is by saying to our shell to create all our tables that we have created inside that Python file.', 'start': 5840.229, 'duration': 9.991}, {'end': 5857.828, 'text': 'And if you remember, our modules are what considered as database tables to our flask application.', 'start': 5850.54, 'duration': 7.288}, {'end': 5861.231, 'text': 'So I will run here DB dot create.', 'start': 5857.928, 'duration': 3.303}, {'end': 5863.053, 'text': 'underscore all.', 'start': 5861.852, 'duration': 1.201}, {'end': 5868.535, 'text': 'And if you do not receive any errors after this command, then you should be totally fine.', 'start': 5863.493, 'duration': 5.042}, {'end': 5879.079, 'text': 'Now once I have executed this, then you should see the market dot DB file right here inside our project directory.', 'start': 5868.955, 'duration': 10.124}, {'end': 5883.861, 'text': 'So that means that we have created database successfully.', 'start': 5879.479, 'duration': 4.382}, {'end': 5885.442, 'text': 'So this is quite great.', 'start': 5883.941, 'duration': 1.501}, {'end': 5889.583, 'text': 'Now currently, our database is totally empty from information.', 'start': 5885.922, 'duration': 3.661}, {'end': 5893.623, 'text': 'So we probably want to go ahead and create some items inside our database.', 'start': 5889.643, 'duration': 3.98}, {'end': 5898.424, 'text': 'And the way we can do that is by accessing our database like Python code.', 'start': 5893.803, 'duration': 4.621}, {'end': 5901.725, 'text': 'So this is what exactly SQL alchemy allows us to do.', 'start': 5898.484, 'duration': 3.241}, {'end': 5911.907, 'text': 'So if by any chance you come from Django world, then you should understand that the SQL alchemy is quite like the object relational mapper of Django.', 'start': 5901.845, 'duration': 10.062}, {'end': 5917.329, 'text': "So this is why we work with the SQL alchemy to OK, so let's go ahead and create some items in here.", 'start': 5911.967, 'duration': 5.362}, {'end': 5921.552, 'text': 'So I will basically import the item model that we have created.', 'start': 5917.429, 'duration': 4.123}, {'end': 5925.594, 'text': 'So it will be from market import item.', 'start': 5921.612, 'duration': 3.982}, {'end': 5931.518, 'text': 'And once I do that, then I can basically go ahead and create an item like that.', 'start': 5926.075, 'duration': 5.443}, {'end': 5935.561, 'text': "So let's create a variable and it will be equal to item one.", 'start': 5931.598, 'duration': 3.963}, {'end': 5939.143, 'text': 'And this will be equal to the item class.', 'start': 5936.081, 'duration': 3.062}, {'end': 5944.627, 'text': 'So we will initialize an item and we will pass in here name equals to phone.', 'start': 5939.223, 'duration': 5.404}, {'end': 5950.879, 'text': "Let's call it iPhone 10 like that.", 'start': 5946.075, 'duration': 4.804}], 'summary': 'Creating a database using flask and adding items to it through sql alchemy.', 'duration': 235.416, 'max_score': 5715.463, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo5715463.jpg'}, {'end': 6314.345, 'src': 'embed', 'start': 6287.001, 'weight': 4, 'content': [{'end': 6292.045, 'text': 'And as well as item.id and also item.barcode.', 'start': 6287.001, 'duration': 5.044}, {'end': 6298.75, 'text': 'Now, once I hit enter here, then we should see all of our results that being shown like here.', 'start': 6292.525, 'duration': 6.225}, {'end': 6306.136, 'text': 'So just remember that you can access each of your fields like we define them inside our module.', 'start': 6299.231, 'duration': 6.905}, {'end': 6314.345, 'text': 'okay. so if we want to filter our objects by some specific condition, this is something that is quite possible as well.', 'start': 6306.636, 'duration': 7.709}], 'summary': 'Demonstrating access and filtering of fields in a module.', 'duration': 27.344, 'max_score': 6287.001, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo6287001.jpg'}], 'start': 4853.211, 'title': 'Flask database configuration and model creation', 'summary': "Covers configuring a sqlite database in a flask application, creating database columns with specific attributes, creating models within flask, and working with item models in python. specific emphasis is placed on creating a 'name' column limited to 30 characters, setting attributes like nullable and unique, and understanding sql alchemy. examples and commands for creating, saving, and querying items are provided.", 'chapters': [{'end': 5294.923, 'start': 4853.211, 'title': 'Flask database configuration', 'summary': "Discusses configuring a sqlite database in a flask application to store organized information using python classes to create database tables, with specific emphasis on creating a 'name' column limited to 30 characters.", 'duration': 441.712, 'highlights': ['The chapter discusses configuring a SQLite database in a Flask application It explains the process of configuring a SQLite database in a Flask application to store organized information.', 'Using Python classes to create database tables It describes the use of Python classes to create database tables for storing organized information.', "Creating a 'name' column limited to 30 characters It explains the process of creating a 'name' column in the database, limited to 30 characters, to avoid storing excessive information."]}, {'end': 5524.434, 'start': 5295.403, 'title': 'Creating database columns with specific attributes', 'summary': 'Discusses creating database columns with specific attributes such as nullable equals to false, unique equals to true, and specifying column types like integer and string.', 'duration': 229.031, 'highlights': ['Creating columns with unique constraints The chapter emphasizes the importance of unique constraints for database columns to ensure each item name is unique, preventing duplications like having two or more items with the same name.', 'Specifying nullable equals to false The transcript highlights the use of nullable equals to false for columns to enforce the non-allowance of null fields, ensuring data integrity within the database.', 'Describing column types like integer and string It discusses specifying column types such as integer and string for database columns to store specific data types, ensuring efficient data storage and retrieval.']}, {'end': 5917.329, 'start': 5524.934, 'title': 'Creating models with flask', 'summary': 'Explains the process of creating models with the flask framework, including the creation of a primary key, configuring the database, and executing commands to create the database file and tables, emphasizing the importance of following conventions and understanding sql alchemy.', 'duration': 392.395, 'highlights': ["The process of creating a primary key 'identifier' field when creating models with Flask framework is explained, emphasizing its importance for unique object recognition within the items (2 occurrences).", "Configuring the database by adding key values to the app object, specifically defining the 'SQLAlchemy_database_URI' to specify the location and name of the database file (2 occurrences).", "Executing the command 'DB.create_all()' to create all the tables defined as modules in the Python file, resulting in the successful creation of the 'market.DB' file in the project directory (2 occurrences).", 'Explanation of how SQL Alchemy allows the creation of items in the database, likening it to the object relational mapper of Django (1 occurrence).', "Importing the 'db' variable from the 'market.py' file to take actions within it, and warnings about future feature deprecation in the Python shell (1 occurrence)."]}, {'end': 6422.516, 'start': 5917.429, 'title': 'Working with item model in python', 'summary': 'Details the process of creating and saving instances of an item model in a database using python, including creating, saving, and querying items, and customizing the display of items, with examples and commands provided.', 'duration': 505.087, 'highlights': ['Creating and saving instances of an item model in a database The chapter explains the process of creating and saving instances of an item model in a database, including creating an item with attributes such as name, price, barcode, and description, and saving the changes to the database using commands like db.session.add and db.session.commit.', 'Querying items and customizing their display The chapter demonstrates how to query items from the database and customize their display, including iterating over items, accessing fields like name, price, description, and barcode, and filtering items based on specific conditions using commands like item.query.all, for item in item.query.all, and item.query.filter_by.', 'Providing examples and commands for practical implementation The chapter provides practical examples and commands for creating, saving, querying, and customizing the display of items, offering a hands-on approach to working with the item model in Python, with specific commands and their expected outputs demonstrated.']}], 'duration': 1569.305, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo4853211.jpg', 'highlights': ["Creating a 'name' column limited to 30 characters", 'Specifying nullable equals to false', 'Creating columns with unique constraints', 'Describing column types like integer and string', 'Configuring the database by adding key values to the app object', "Executing the command 'DB.create_all()' to create all the tables defined as modules in the Python file", 'Creating and saving instances of an item model in a database', 'Querying items and customizing their display', 'Providing examples and commands for practical implementation']}, {'end': 7794.789, 'segs': [{'end': 6596.525, 'src': 'embed', 'start': 6563.416, 'weight': 3, 'content': [{'end': 6570.377, 'text': 'But basically this is something that you maybe want to do because you want to really have an actual look for what is inside your database.', 'start': 6563.416, 'duration': 6.961}, {'end': 6576.959, 'text': "So, since I'm using Windows machine currently, then I already have downloaded this software,", 'start': 6570.798, 'duration': 6.161}, {'end': 6582.921, 'text': "and then I'm going to display you how you can browse your information in a visual graphical interface.", 'start': 6576.959, 'duration': 5.962}, {'end': 6584.321, 'text': "So let's go ahead and have a look.", 'start': 6582.981, 'duration': 1.34}, {'end': 6596.525, 'text': 'okay, so i will open our sqlite3 weaver and in here what i have to do is only browsing the file of our database files.', 'start': 6584.821, 'duration': 11.704}], 'summary': 'Demonstrating how to browse database files using sqlite3 weaver on a windows machine.', 'duration': 33.109, 'max_score': 6563.416, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo6563416.jpg'}, {'end': 6849.944, 'src': 'embed', 'start': 6816.398, 'weight': 2, 'content': [{'end': 6824.223, 'text': 'So again, we could try to solve that by moving that line to modules.py.', 'start': 6816.398, 'duration': 7.825}, {'end': 6827.465, 'text': 'So I will paste this in inside here.', 'start': 6824.303, 'duration': 3.162}, {'end': 6833.51, 'text': 'Now we also end up with Missing the SQL alchemy instance.', 'start': 6827.945, 'duration': 5.565}, {'end': 6841.417, 'text': 'So again, we could grab this in from here and paste this in above here.', 'start': 6833.97, 'duration': 7.447}, {'end': 6849.944, 'text': 'But we are never going to get out of this because there is always going to be something missing in each file.', 'start': 6841.837, 'duration': 8.107}], 'summary': 'Attempting to solve missing sql alchemy instance by moving code to modules.py.', 'duration': 33.546, 'max_score': 6816.398, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo6816398.jpg'}, {'end': 7550.399, 'src': 'heatmap', 'start': 6855.789, 'weight': 0.722, 'content': [{'end': 6863.952, 'text': 'Now, what circular imports are? It is basically two files are trying to import from each other.', 'start': 6855.789, 'duration': 8.163}, {'end': 6867.054, 'text': 'And it is something that is forbidden in Python,', 'start': 6864.432, 'duration': 2.622}, {'end': 6875.217, 'text': 'because each file will end up with some missing variables when it tries to load some variable from Python memory.', 'start': 6867.054, 'duration': 8.163}, {'end': 6880.739, 'text': 'So in order to avoid this, Python comes up with something that is named packages.', 'start': 6875.677, 'duration': 5.062}, {'end': 6887.221, 'text': 'Now we can basically package our entire application inside a new directory.', 'start': 6881.119, 'duration': 6.102}, {'end': 6889.361, 'text': "Let's call it something like market.", 'start': 6887.521, 'duration': 1.84}, {'end': 6892.722, 'text': 'And then we can create one more Python file.', 'start': 6889.741, 'duration': 2.981}, {'end': 6896.643, 'text': 'For example, we can name it run, execute, start something like that.', 'start': 6893.042, 'duration': 3.601}, {'end': 6902.245, 'text': 'And then that Python file will know how to import everything step by step.', 'start': 6897.103, 'duration': 5.142}, {'end': 6907.366, 'text': 'And the only thing that we will have to do is calling that specific file.', 'start': 6902.705, 'duration': 4.661}, {'end': 6911.207, 'text': 'And then that Python file will take care of the rest.', 'start': 6907.706, 'duration': 3.501}, {'end': 6917.048, 'text': 'So this is the design that we are going to implement in that video, And so by the end of this video,', 'start': 6911.207, 'duration': 5.841}, {'end': 6922.289, 'text': 'every file will be at its own place and everything will totally make sense for you.', 'start': 6917.048, 'duration': 5.241}, {'end': 6932.614, 'text': "So let's actually get rid of those lines that I just pasted in over here and Revert them back inside our market dot py,", 'start': 6922.289, 'duration': 10.325}, {'end': 6939.06, 'text': 'and then we will remove those again, And then now we will basically go ahead and create a package and then we will name it market.', 'start': 6932.614, 'duration': 6.446}, {'end': 6941.382, 'text': "So let's see how we can do that great.", 'start': 6939.06, 'duration': 2.322}, {'end': 6942.843, 'text': 'so first of all,', 'start': 6941.382, 'duration': 1.461}, {'end': 6951.931, 'text': 'we will go ahead inside our flask market directory and We will create that single file that is going to take care of everything that I just discussed about,', 'start': 6942.843, 'duration': 9.088}, {'end': 6954.573, 'text': 'and I will name it something like run.', 'start': 6951.931, 'duration': 2.642}, {'end': 6958.515, 'text': 'okay, so it is going to be responsible to execute our application,', 'start': 6954.573, 'duration': 3.942}, {'end': 6970.761, 'text': 'and what i will do now is grab everything from our market.py and i will cut everything from here and i will basically paste this in over here.', 'start': 6958.515, 'duration': 12.246}, {'end': 6981.752, 'text': 'Now, as I have completed this, basically I can allow myself to delete the market.py file, because the routes are here and then the models are here.', 'start': 6971.321, 'duration': 10.431}, {'end': 6986.297, 'text': 'So the market.py is quite empty and I can allow myself to delete that.', 'start': 6981.812, 'duration': 4.485}, {'end': 6987.899, 'text': "So let's go ahead and delete that.", 'start': 6986.377, 'duration': 1.522}, {'end': 6990.382, 'text': 'I will use the save delete option.', 'start': 6988.78, 'duration': 1.602}, {'end': 7001.923, 'text': 'right, and our next step here will be to create new directory and move our templates, modules and routes.py into that directory.', 'start': 6991.292, 'duration': 10.631}, {'end': 7008.27, 'text': 'so we are packaging every flask element into a new directory that is named market.', 'start': 7001.923, 'duration': 6.347}, {'end': 7021.54, 'text': "so let's go ahead and create a new directory here and I will name it market and then we will basically move everything from Here to that market directory.", 'start': 7008.27, 'duration': 13.27}, {'end': 7029.527, 'text': 'So in PyCharm that will be as easy as grabbing it and Just hovering it inside the market here.', 'start': 7022.001, 'duration': 7.526}, {'end': 7037.874, 'text': 'Then you can see that PyCharm auto completes me by asking if I want to move some files into that directory.', 'start': 7029.887, 'duration': 7.987}, {'end': 7041.137, 'text': 'So I will basically use the refactor option here.', 'start': 7037.974, 'duration': 3.163}, {'end': 7046.501, 'text': 'And then you can see that our modules, for example, is located inside the new directory.', 'start': 7041.157, 'duration': 5.344}, {'end': 7052.667, 'text': 'Now I will do the same with routes and also with our templates.', 'start': 7046.922, 'duration': 5.745}, {'end': 7059.854, 'text': 'Great, and last, we will also move in our market.db.', 'start': 7055.029, 'duration': 4.825}, {'end': 7062.516, 'text': "Okay, so let's close each file over here.", 'start': 7060.094, 'duration': 2.422}, {'end': 7075.008, 'text': 'So our structure right now is that we have our market directory and we have our run.py Python file, which is outside of that market directory.', 'start': 7062.977, 'duration': 12.031}, {'end': 7077.29, 'text': "So let's see how we continue from here.", 'start': 7075.188, 'duration': 2.102}, {'end': 7083.014, 'text': 'Okay, so if we actually take a look to the lines that are left inside our run.py file,', 'start': 7077.29, 'duration': 5.724}, {'end': 7090.741, 'text': 'They are basically some initialization lines that contains very important information about our web application.', 'start': 7083.014, 'duration': 7.727}, {'end': 7101.188, 'text': 'Now what we must do with those lines of code that are left over here is to move them to a special Python file that is called double underscore init.', 'start': 7091.221, 'duration': 9.967}, {'end': 7111.055, 'text': 'Now when you work with Python packages, every Python package that is considered as a regular package is going to include one special Python file.', 'start': 7101.648, 'duration': 9.407}, {'end': 7116.501, 'text': 'That its name is always going to be double underscore, init, double underscore.', 'start': 7111.375, 'duration': 5.126}, {'end': 7125.351, 'text': 'And what is so special with that file is that when you import it, Then, before it loads what you want to import to your file,', 'start': 7116.501, 'duration': 8.85}, {'end': 7131.899, 'text': 'It is basically going to execute that particular file that is named double underscore, init, double underscore.', 'start': 7125.351, 'duration': 6.548}, {'end': 7138.621, 'text': 'So it totally makes sense, because whenever we want to import some objects or variables from our application,', 'start': 7132.299, 'duration': 6.322}, {'end': 7147.765, 'text': 'then we probably want to execute those lines of code, because those lines of code are what responsible to start our flask application.', 'start': 7138.621, 'duration': 9.144}, {'end': 7149.826, 'text': 'So we will go ahead and do that.', 'start': 7148.205, 'duration': 1.621}, {'end': 7164.255, 'text': 'So I will basically go inside our market directory and I will create an initialization File that will be responsible to define this directory as a package.', 'start': 7150.186, 'duration': 14.069}, {'end': 7168.518, 'text': 'So I will name it double underscore, init, double underscore, as I said,', 'start': 7164.635, 'duration': 3.883}, {'end': 7176.566, 'text': 'and I will move in whatever is inside that run.py to that double underscore init.', 'start': 7168.518, 'duration': 8.048}, {'end': 7177.587, 'text': 'double underscore file.', 'start': 7176.566, 'duration': 1.021}, {'end': 7189.359, 'text': 'Now, what is so special with the process that we have done until now is that if we are going ahead from our run dot py file and we try to import market,', 'start': 7178.107, 'duration': 11.252}, {'end': 7195.045, 'text': 'then it is going to recognize it as a package because we have included that double underscore init file.', 'start': 7189.359, 'duration': 5.686}, {'end': 7200.81, 'text': 'So if we were to try to import that app variable that we have created,', 'start': 7195.405, 'duration': 5.405}, {'end': 7208.514, 'text': 'then it is going to be perfectly fine because it recognizes that variable from our double underscore init file.', 'start': 7200.81, 'duration': 7.704}, {'end': 7214.938, 'text': 'And anyway, it is going to execute it as the first step because this is why we have that double underscore init file.', 'start': 7208.895, 'duration': 6.043}, {'end': 7220.542, 'text': 'And actually, the next line that I can allow myself to do here is using app dot run.', 'start': 7215.279, 'duration': 5.263}, {'end': 7227.464, 'text': 'And this file is going to be that pointer file that is going to do the rest of the job of importing everything.', 'start': 7221.082, 'duration': 6.382}, {'end': 7235.587, 'text': 'So this is how it is going to work, right? We are basically going to import our application from market package and then we are going to run it.', 'start': 7227.844, 'duration': 7.743}, {'end': 7241.011, 'text': "But before we actually try this out, let's add here one more argument.", 'start': 7236.007, 'duration': 5.004}, {'end': 7245.475, 'text': 'And it is going to accept some arguments that we already familiar with.', 'start': 7241.512, 'duration': 3.963}, {'end': 7248.638, 'text': 'And it is going to accept here debug equals true.', 'start': 7245.816, 'duration': 2.822}, {'end': 7252.502, 'text': "So we don't have to set up those environment variables anymore.", 'start': 7249.039, 'duration': 3.463}, {'end': 7262.911, 'text': "And one more thing that I'd like to add here as a convention in Python is to test out if this run.py file has executed directly.", 'start': 7252.922, 'duration': 9.989}, {'end': 7274.46, 'text': 'Now, the way that we can check that is by writing the conditional of if double underscore name is equal to double underscore main.', 'start': 7263.331, 'duration': 11.129}, {'end': 7283.147, 'text': "And again, if you don't know what this conditional is about, I have a video on my channel that you can definitely check out what this special,", 'start': 7274.84, 'duration': 8.307}, {'end': 7285.349, 'text': 'if name equals main does.', 'start': 7283.147, 'duration': 2.202}, {'end': 7290.293, 'text': 'But basically, it checks if our run.py file has executed directly.', 'start': 7285.689, 'duration': 4.604}, {'end': 7298.199, 'text': "Okay, so now let's go ahead to our terminal and try to see what will happen if we execute that run.py file.", 'start': 7290.433, 'duration': 7.766}, {'end': 7302.642, 'text': 'Now I know that there is a great chance that we are going to fail and receive some errors.', 'start': 7298.639, 'duration': 4.003}, {'end': 7309.788, 'text': 'But I want to show you step by step how we are going to overcome those errors now that we have our package set up.', 'start': 7303.063, 'duration': 6.725}, {'end': 7311.769, 'text': 'So I will open my terminal.', 'start': 7310.168, 'duration': 1.601}, {'end': 7318.715, 'text': 'And basically, the only thing that I have to do now is going ahead and execute that run.py file.', 'start': 7312.29, 'duration': 6.425}, {'end': 7330.083, 'text': 'now our web application will start and if we actually try to access it, then you can see that we receive errors, that the root url is not found.', 'start': 7319.275, 'duration': 10.808}, {'end': 7335.446, 'text': "now that doesn't make sense, because if we take a look to our python,", 'start': 7330.083, 'duration': 5.363}, {'end': 7343.051, 'text': 'then we can see inside our routes.py that that we have the route for our root url.', 'start': 7335.446, 'duration': 7.605}, {'end': 7354.176, 'text': 'but the reason this fails it is because the double underscore init file does not recognize the route that we have created inside that route.py file.', 'start': 7343.051, 'duration': 11.125}, {'end': 7364.421, 'text': 'so our first step here is going to be to complete this thunder init file by saying from market import routes.', 'start': 7354.176, 'duration': 10.245}, {'end': 7374.425, 'text': 'And as you remember, if we import certain file, then Python is going to try to execute what is inside that file.', 'start': 7364.921, 'duration': 9.504}, {'end': 7380.407, 'text': 'So now we can go back to our web browser and the tester results out.', 'start': 7374.785, 'duration': 5.622}, {'end': 7387.35, 'text': "Now you can see that our web application is probably down right now because we see that this site can't be reached.", 'start': 7380.708, 'duration': 6.642}, {'end': 7391.952, 'text': 'And as you can see, we started to receive certain errors about the import.', 'start': 7387.81, 'duration': 4.142}, {'end': 7398.395, 'text': "So in that route dot py file, we don't have the application defined.", 'start': 7392.492, 'duration': 5.903}, {'end': 7400.195, 'text': "So let's go ahead and fix that.", 'start': 7398.755, 'duration': 1.44}, {'end': 7411.242, 'text': 'So I will go to our Python and I will basically type in From market, import app.', 'start': 7400.616, 'duration': 10.626}, {'end': 7418.429, 'text': 'And as you can see that app errors are started to disappear, but we still have left with the render template error.', 'start': 7411.542, 'duration': 6.887}, {'end': 7426.316, 'text': 'So we can also go ahead and fix it by saying from flask, import render template.', 'start': 7418.789, 'duration': 7.527}, {'end': 7432.017, 'text': 'And then we also have one more error that we must fix in here.', 'start': 7426.796, 'duration': 5.221}, {'end': 7435.558, 'text': 'And that will be the import of our models.py.', 'start': 7432.417, 'duration': 3.141}, {'end': 7440.398, 'text': 'Because as you can see, we have a line here that says item.query.all.', 'start': 7435.598, 'duration': 4.8}, {'end': 7444.859, 'text': "And it doesn't know anything about it because it is not a recognized module.", 'start': 7440.898, 'duration': 3.961}, {'end': 7449.54, 'text': 'And I can basically import it like we can import from a regular package in Python.', 'start': 7444.979, 'duration': 4.561}, {'end': 7454.981, 'text': 'And that will be by saying from market.modules.py.', 'start': 7450, 'duration': 4.981}, {'end': 7457.362, 'text': 'import item.', 'start': 7455.661, 'duration': 1.701}, {'end': 7464.967, 'text': 'so now we have pretty much everything set up in our routes.py, and if we have a look inside our models.py,', 'start': 7457.362, 'duration': 7.605}, {'end': 7468.149, 'text': 'then we still have some errors over here left over.', 'start': 7464.967, 'duration': 3.182}, {'end': 7481.1, 'text': 'so i can basically fix it by saying from market import db, because we can import it from our dunder init file and now everything should work.', 'start': 7468.149, 'duration': 12.951}, {'end': 7493.256, 'text': 'so we can basically test this up by going to our terminal and rerun our application and i will clean my screen again and i will try to run that py file again.', 'start': 7481.1, 'duration': 12.156}, {'end': 7499.288, 'text': 'And now our website is up and running and I can basically test if everything works properly.', 'start': 7493.883, 'duration': 5.405}, {'end': 7504.954, 'text': "And if I refresh it, then you can see that we receive our web application as it's supposed to.", 'start': 7499.629, 'duration': 5.325}, {'end': 7510.659, 'text': 'Now, if I navigate to that market page, then you can also see that everything is quite great.', 'start': 7505.374, 'duration': 5.285}, {'end': 7517.266, 'text': 'So this means that everything works great and we have completed our packaging successfully.', 'start': 7511.14, 'duration': 6.126}, {'end': 7521.929, 'text': 'Now. I know that there was a lot of information that will probably have to sink in,', 'start': 7517.626, 'duration': 4.303}, {'end': 7527.513, 'text': 'but I hope that the packaging process was clear and you pretty much understood everything about what I have done here.', 'start': 7521.929, 'duration': 5.584}, {'end': 7537.1, 'text': 'So again, the main idea was to package everything that is related to market and then having one single file that we basically can execute it.', 'start': 7527.774, 'duration': 9.326}, {'end': 7540.423, 'text': 'And then this file will be responsible to do everything for us.', 'start': 7537.461, 'duration': 2.962}, {'end': 7550.399, 'text': 'Now, I just realized that I did not specify a lot of times throughout this tutorial that our code is available from the GitHub.', 'start': 7543.416, 'duration': 6.983}], 'summary': 'Python package implemented to resolve circular imports issue, resulting in successful application execution.', 'duration': 694.61, 'max_score': 6855.789, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo6855789.jpg'}, {'end': 6902.245, 'src': 'embed', 'start': 6875.677, 'weight': 8, 'content': [{'end': 6880.739, 'text': 'So in order to avoid this, Python comes up with something that is named packages.', 'start': 6875.677, 'duration': 5.062}, {'end': 6887.221, 'text': 'Now we can basically package our entire application inside a new directory.', 'start': 6881.119, 'duration': 6.102}, {'end': 6889.361, 'text': "Let's call it something like market.", 'start': 6887.521, 'duration': 1.84}, {'end': 6892.722, 'text': 'And then we can create one more Python file.', 'start': 6889.741, 'duration': 2.981}, {'end': 6896.643, 'text': 'For example, we can name it run, execute, start something like that.', 'start': 6893.042, 'duration': 3.601}, {'end': 6902.245, 'text': 'And then that Python file will know how to import everything step by step.', 'start': 6897.103, 'duration': 5.142}], 'summary': 'Python uses packages to organize and import applications, enhancing modularity.', 'duration': 26.568, 'max_score': 6875.677, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo6875677.jpg'}, {'end': 7037.874, 'src': 'embed', 'start': 7008.27, 'weight': 0, 'content': [{'end': 7021.54, 'text': "so let's go ahead and create a new directory here and I will name it market and then we will basically move everything from Here to that market directory.", 'start': 7008.27, 'duration': 13.27}, {'end': 7029.527, 'text': 'So in PyCharm that will be as easy as grabbing it and Just hovering it inside the market here.', 'start': 7022.001, 'duration': 7.526}, {'end': 7037.874, 'text': 'Then you can see that PyCharm auto completes me by asking if I want to move some files into that directory.', 'start': 7029.887, 'duration': 7.987}], 'summary': 'Creating a new directory named market and moving everything into it in pycharm.', 'duration': 29.604, 'max_score': 7008.27, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo7008270.jpg'}, {'end': 7116.501, 'src': 'embed', 'start': 7091.221, 'weight': 1, 'content': [{'end': 7101.188, 'text': 'Now what we must do with those lines of code that are left over here is to move them to a special Python file that is called double underscore init.', 'start': 7091.221, 'duration': 9.967}, {'end': 7111.055, 'text': 'Now when you work with Python packages, every Python package that is considered as a regular package is going to include one special Python file.', 'start': 7101.648, 'duration': 9.407}, {'end': 7116.501, 'text': 'That its name is always going to be double underscore, init, double underscore.', 'start': 7111.375, 'duration': 5.126}], 'summary': 'Move leftover code to a special python file called double underscore init for regular python packages.', 'duration': 25.28, 'max_score': 7091.221, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo7091221.jpg'}, {'end': 7779.861, 'src': 'embed', 'start': 7755.572, 'weight': 5, 'content': [{'end': 7762.777, 'text': "Now I'm going to name this field a little bit different because we are not going to store passwords as plain text inside our database.", 'start': 7755.572, 'duration': 7.205}, {'end': 7766.398, 'text': 'Now, doing something like this could lead to a lot of security risks.', 'start': 7763.217, 'duration': 3.181}, {'end': 7774.36, 'text': "And that is something that is basically could make hackers life easier to pull some information from your website's database.", 'start': 7766.798, 'duration': 7.562}, {'end': 7779.861, 'text': 'So you probably want to avoid this by storing the password, not as plain text.', 'start': 7774.72, 'duration': 5.141}], 'summary': "Storing passwords as plain text poses security risks and can make hackers' lives easier to pull information from the website's database.", 'duration': 24.289, 'max_score': 7755.572, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo7755572.jpg'}], 'start': 6422.756, 'title': 'Updating database and inspecting sqlite 3', 'summary': 'Covers updating database with real data, querying all objects, inspecting sqlite 3 database using visual interface, and implementing python circular imports and packaging, including creating database models and ensuring password security.', 'chapters': [{'end': 6510.602, 'start': 6422.756, 'title': 'Updating database information and querying all objects', 'summary': 'Explains how to update dummy information with real data in a database and query all objects, demonstrating the process through executing code and displaying the updated information on a website.', 'duration': 87.846, 'highlights': ['Once saved, executing the server and refreshing the website display the updated information from the database, ensuring the correct functioning of the process.', "Using 'item.query.all' returns all objects of 'items' stored in the database, simplifying the process of querying and retrieving data.", 'Updating the dummy information with real data in the database facilitates the accurate display of information on the website, demonstrating the practical implementation of the database update process.']}, {'end': 6849.944, 'start': 6510.982, 'title': 'Inspecting sqlite 3 database in visual interface', 'summary': 'Discusses how to inspect an sqlite 3 database using a visual graphical user interface, including downloading a suitable browser, browsing the database, and reorganizing flask elements into different python files.', 'duration': 338.962, 'highlights': ['The chapter discusses how to inspect an SQLite 3 database using a visual graphical user interface. The chapter explains the process of inspecting an SQLite 3 database using a visual graphical user interface to gain a clear visual understanding of the database structure and contents.', 'Downloading a suitable browser for SQLite 3 is recommended for visually viewing the database. The recommendation is to download a browser for SQLite 3, which offers download options for various operating systems, allowing visual viewing of database contents.', 'Reorganizing flask elements into different Python files is discussed for better project organization. The process of reorganizing flask elements into separate Python files, such as models.py and routes.py, is explained to enhance project organization and management.']}, {'end': 7241.011, 'start': 6850.324, 'title': 'Python circular imports and package implementation', 'summary': 'Explains the concept of circular imports in python and the implementation of packages to avoid it, showcasing the process of packaging the application inside a new directory named market and creating an initialization file to define the directory as a package.', 'duration': 390.687, 'highlights': ["Python comes up with packages to avoid circular imports, allowing the entire application to be packaged inside a new directory, such as 'market', and creating a Python file to handle the imports step by step.", 'The process involves creating a new directory named market, moving the necessary files into it, and then deleting the empty market.py file to ensure each file is at its own place.', 'Special Python file named double underscore init, double underscore is created to define the directory as a package and contain important initialization lines for the web application.', 'The double underscore init file ensures that the directory is recognized as a package when importing and executes the necessary initialization lines before importing variables from the application.', 'The implementation involves importing the application from the market package and running it using app.run, with the added argument to be included before trying it out.']}, {'end': 7794.789, 'start': 7241.512, 'title': 'Python packaging and database model creation', 'summary': 'Details the process of packaging a python application, overcoming errors, creating database models, and ensuring password security.', 'duration': 553.277, 'highlights': ['The chapter covers the process of packaging a Python application, including setting up environment variables and checking if the run.py file has executed directly.', 'The author demonstrates overcoming errors step by step, including resolving import errors and completing the init file.', 'Database model creation is explained, with a focus on creating fields for username, email address, and password, while emphasizing the need for password encryption to enhance security.', 'The tutorial emphasizes the availability of the code on GitHub and encourages viewers to access it for reference and further understanding.', 'The need to store user information in a database is highlighted, with a focus on creating a new module for user information and defining fields such as username, email address, and password with specific constraints.']}], 'duration': 1372.033, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo6422756.jpg', 'highlights': ['Updating the dummy information with real data in the database facilitates the accurate display of information on the website, demonstrating the practical implementation of the database update process.', "Using 'item.query.all' returns all objects of 'items' stored in the database, simplifying the process of querying and retrieving data.", 'The chapter discusses how to inspect an SQLite 3 database using a visual graphical user interface, providing a clear visual understanding of the database structure and contents.', 'Reorganizing flask elements into different Python files is explained to enhance project organization and management.', "Python comes up with packages to avoid circular imports, allowing the entire application to be packaged inside a new directory, such as 'market', and creating a Python file to handle the imports step by step.", 'The process involves creating a new directory named market, moving the necessary files into it, and then deleting the empty market.py file to ensure each file is at its own place.', 'Special Python file named double underscore init, double underscore is created to define the directory as a package and contain important initialization lines for the web application.', 'The chapter covers the process of packaging a Python application, including setting up environment variables and checking if the run.py file has executed directly.', 'Database model creation is explained, with a focus on creating fields for username, email address, and password, while emphasizing the need for password encryption to enhance security.', 'The tutorial emphasizes the availability of the code on GitHub and encourages viewers to access it for reference and further understanding.', 'The need to store user information in a database is highlighted, with a focus on creating a new module for user information and defining fields such as username, email address, and password with specific constraints.']}, {'end': 8714.444, 'segs': [{'end': 7819.34, 'src': 'embed', 'start': 7794.789, 'weight': 1, 'content': [{'end': 7806.845, 'text': 'so i will name this field by saying password underscore hash, and that will be equal to db.column, and we are going to receive here string again.', 'start': 7794.789, 'duration': 12.056}, {'end': 7810.189, 'text': "Now I'm going to give this length 60,", 'start': 7807.345, 'duration': 2.844}, {'end': 7819.34, 'text': 'because the mostly used hashing algorithm that flask allows us to use will always convert the passwords to being 60 characters.', 'start': 7810.189, 'duration': 9.151}], 'summary': "Defining 'password_hash' field as db.column with length 60 for secure password hashing.", 'duration': 24.551, 'max_score': 7794.789, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo7794789.jpg'}, {'end': 7869.43, 'src': 'embed', 'start': 7844.947, 'weight': 2, 'content': [{'end': 7852.274, 'text': 'Now if you remember from the very beginning of this tutorial, I said that we are going to apply a budget system for our users.', 'start': 7844.947, 'duration': 7.327}, {'end': 7859.881, 'text': 'So it totally makes sense to describe our users attributes by one more attribute that its name will be budget.', 'start': 7852.574, 'duration': 7.307}, {'end': 7864.946, 'text': 'So I will go ahead and say budget equals to DB dot column.', 'start': 7860.062, 'duration': 4.884}, {'end': 7869.43, 'text': 'And that time, this will be equal to DB dot integer.', 'start': 7865.587, 'duration': 3.843}], 'summary': "Implementing a budget system for users with the attribute 'budget' being set to db.column, which will be equal to db.integer.", 'duration': 24.483, 'max_score': 7844.947, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo7844947.jpg'}, {'end': 7924.994, 'src': 'embed', 'start': 7896.033, 'weight': 6, 'content': [{'end': 7902.597, 'text': 'So the users can at least have 1000 coins at the very first registration attempt.', 'start': 7896.033, 'duration': 6.564}, {'end': 7905.679, 'text': 'Okay, so it totally makes sense to set up a value like that.', 'start': 7902.817, 'duration': 2.862}, {'end': 7915.745, 'text': 'And one final field that I like to add here before we close up this model will be a field that is going to be related to our items model.', 'start': 7905.979, 'duration': 9.766}, {'end': 7924.994, 'text': 'Now what that means, it means that we want to allow our users to own several items because this is what this website is going to be about.', 'start': 7915.925, 'duration': 9.069}], 'summary': 'Users receive 1000 coins at first registration, and can own multiple items.', 'duration': 28.961, 'max_score': 7896.033, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo7896033.jpg'}, {'end': 8688.665, 'src': 'heatmap', 'start': 7999.069, 'weight': 0.773, 'content': [{'end': 8004.015, 'text': 'we are basically going to grab the object of the user and we will access the attribute of items.', 'start': 7999.069, 'duration': 4.946}, {'end': 8011.656, 'text': "But let's consider a situation that you have an iPhone item inside your database and you want to know its owner.", 'start': 8004.235, 'duration': 7.421}, {'end': 8019.438, 'text': 'Now you are going to grab the item object and then you will access it by the attribute of owned user.', 'start': 8012.096, 'duration': 7.342}, {'end': 8024.799, 'text': 'And that is because you specify the back reference of that item.', 'start': 8019.838, 'duration': 4.961}, {'end': 8031.68, 'text': 'So it is quite important to provide this back reference because it will allow us to see the owner of specific items.', 'start': 8024.859, 'duration': 6.821}, {'end': 8039.062, 'text': 'So the last argument that I will say here will be lazy equals true, and that is something that we also have to set up here,', 'start': 8031.84, 'duration': 7.222}, {'end': 8048.105, 'text': "because if you don't set up the lazy equals true, then the SQL alchemy will not grab all the objects of items in one shot.", 'start': 8039.062, 'duration': 9.043}, {'end': 8052.366, 'text': 'So it is quite important to specify the lazy equals true in that case.', 'start': 8048.245, 'duration': 4.121}, {'end': 8059.634, 'text': 'Now I want you to take a look how this DB is not actually a column besides it is a relationship.', 'start': 8052.546, 'duration': 7.088}, {'end': 8067.022, 'text': 'So what that means, it means that this is not actually going to be stored as a column when we try to inspect inside our database.', 'start': 8060.114, 'duration': 6.908}, {'end': 8075.469, 'text': 'So it is quite wrong because we also want to store information about certain users that are owning some items.', 'start': 8067.523, 'duration': 7.946}, {'end': 8082.973, 'text': 'Now, the way that we are going to do that is by saying to our items module which user is owning it.', 'start': 8075.609, 'duration': 7.364}, {'end': 8092.617, 'text': 'So we will go back to our items module and specify one more column that we must create in order to make this relationship to work successfully.', 'start': 8083.173, 'duration': 9.444}, {'end': 8099.301, 'text': 'So we will go here and we will type in owner equals to db.column.', 'start': 8092.998, 'duration': 6.303}, {'end': 8102.843, 'text': 'and this will be an integer.', 'start': 8100.061, 'duration': 2.782}, {'end': 8107.187, 'text': 'and the next thing that we want to write here is the relationship to the user model.', 'start': 8102.843, 'duration': 4.344}, {'end': 8120.198, 'text': 'so i will say db dot, foreign key like this now, what foreign key does it serves for the primary key of your model from the module that is related to?', 'start': 8107.187, 'duration': 13.011}, {'end': 8121.879, 'text': 'now? if you remember,', 'start': 8120.698, 'duration': 1.181}, {'end': 8135.404, 'text': 'i said previously that there is a great reason that we have to create this id in here in order to the sql alchemy to understand each row that is going to be stored inside our databases.', 'start': 8121.879, 'duration': 13.525}, {'end': 8145.829, 'text': 'so now, if we go ahead and create foreign key, we can basically say that this foreign key is going to be related to the other modules primary key.', 'start': 8135.404, 'duration': 10.425}, {'end': 8149.671, 'text': 'so we will say in here user dot ID.', 'start': 8145.829, 'duration': 3.842}, {'end': 8158.337, 'text': 'And this is related to the each unique row that is going to be stored in that ID.', 'start': 8150.151, 'duration': 8.186}, {'end': 8163.66, 'text': 'So it is quite important to write here user dot ID in lowercase.', 'start': 8158.397, 'duration': 5.263}, {'end': 8166.082, 'text': "Okay, so now I'm back at my terminal.", 'start': 8163.94, 'duration': 2.142}, {'end': 8170.565, 'text': 'And I like to create all the tables from scratch inside our database.', 'start': 8166.502, 'duration': 4.063}, {'end': 8172.346, 'text': 'So we will go with Python.', 'start': 8170.625, 'duration': 1.721}, {'end': 8176.589, 'text': 'And we will use here from market dot modules.', 'start': 8172.846, 'duration': 3.743}, {'end': 8179.062, 'text': 'import DB.', 'start': 8177.961, 'duration': 1.101}, {'end': 8183.925, 'text': 'And then we can basically say DB dot drop all.', 'start': 8179.602, 'duration': 4.323}, {'end': 8189.689, 'text': 'Now this will delete entire information from your database, including all the tables.', 'start': 8184.405, 'duration': 5.284}, {'end': 8193.992, 'text': 'So we will say that and then we will recreate everything.', 'start': 8189.929, 'duration': 4.063}, {'end': 8202.183, 'text': "now. i'm doing this just because we want to clean our information before we test new things out, but in production, when you add a new table,", 'start': 8194.614, 'duration': 7.569}, {'end': 8205.005, 'text': "you don't always have to delete the entire information.", 'start': 8202.183, 'duration': 2.822}, {'end': 8213.674, 'text': 'basically, you could also execute create underscore all, but i just wanted to show you that there is the option of drop underscore all as well.', 'start': 8205.005, 'duration': 8.669}, {'end': 8220.08, 'text': "so now, if i go ahead and create everything, Then if I don't receive errors, then it means that everything looks great.", 'start': 8213.674, 'duration': 6.406}, {'end': 8223.821, 'text': 'Now we can continue by importing the models.', 'start': 8220.559, 'duration': 3.262}, {'end': 8229.984, 'text': 'So we will say import user and item again from our market.modules.', 'start': 8223.901, 'duration': 6.083}, {'end': 8235.306, 'text': 'Now we can basically try to create a new user to see if everything has worked properly.', 'start': 8230.224, 'duration': 5.082}, {'end': 8241.409, 'text': 'So we will say u1 equals to user and we will specify the username.', 'start': 8235.686, 'duration': 5.723}, {'end': 8247.151, 'text': 'This will be equal to JSC for example, and we will write in password underscore hash.', 'start': 8241.949, 'duration': 5.202}, {'end': 8251.352, 'text': 'This will be equal to just random string numbers.', 'start': 8247.87, 'duration': 3.482}, {'end': 8259.035, 'text': 'And we will also say email equals to something like the following.', 'start': 8251.972, 'duration': 7.063}, {'end': 8263.697, 'text': 'Now, if you remember, we also have the fields of budget and the owner.', 'start': 8259.235, 'duration': 4.462}, {'end': 8267.918, 'text': 'Now I did not specify nullable equals to false on both of those.', 'start': 8264.177, 'duration': 3.741}, {'end': 8270.659, 'text': 'So that means that it should be enough.', 'start': 8268.397, 'duration': 2.262}, {'end': 8275.451, 'text': 'Now I guess I missed the email here.', 'start': 8273.311, 'duration': 2.14}, {'end': 8278.594, 'text': 'So we should fix that to underscore address.', 'start': 8275.513, 'duration': 3.081}, {'end': 8280.516, 'text': 'And now we are fine.', 'start': 8279.415, 'duration': 1.101}, {'end': 8282.897, 'text': "Now let's clean the screen a bit.", 'start': 8281.016, 'duration': 1.881}, {'end': 8285.718, 'text': 'We will say OS.System.', 'start': 8283.317, 'duration': 2.401}, {'end': 8289.041, 'text': 'And we will execute this CLS inside here.', 'start': 8285.939, 'duration': 3.102}, {'end': 8294.065, 'text': 'And now I can basically go with db.Session.Add.', 'start': 8289.062, 'duration': 5.003}, {'end': 8296.986, 'text': 'And we will add the U1 in here.', 'start': 8294.645, 'duration': 2.341}, {'end': 8302.731, 'text': 'And we can commit our changes by saying db.Session.', 'start': 8297.627, 'duration': 5.104}, {'end': 8309.558, 'text': 'Okay, so now this should be enough for our user to be stored inside our database.', 'start': 8303.63, 'duration': 5.928}, {'end': 8314.764, 'text': 'Now to see this, we can basically execute user.query.all.', 'start': 8309.898, 'duration': 4.866}, {'end': 8320.892, 'text': 'And then you can see that we have one user with the user one statement right here.', 'start': 8314.785, 'duration': 6.107}, {'end': 8323.333, 'text': 'So it means that everything worked great.', 'start': 8321.312, 'duration': 2.021}, {'end': 8325.674, 'text': 'Okay, so I cleaned the screen a little bit here.', 'start': 8323.493, 'duration': 2.181}, {'end': 8330.097, 'text': 'So I also want to test up the relationship if it works great.', 'start': 8325.834, 'duration': 4.263}, {'end': 8337.842, 'text': 'So we can basically create several items quickly and set their owners to the user that we have just created and see if everything works well.', 'start': 8330.217, 'duration': 7.625}, {'end': 8347.868, 'text': 'So I will go ahead and say I1 equals to an item and I will go by saying the name equals to iPhone 10 for example.', 'start': 8338.281, 'duration': 9.587}, {'end': 8361.361, 'text': 'and we will type in description and we will just write in a short description here and we will say barcode equals to a string like that and we will type in price equals to 800,', 'start': 8348.327, 'duration': 13.034}, {'end': 8362.423, 'text': 'for example.', 'start': 8361.361, 'duration': 1.062}, {'end': 8367.075, 'text': 'So I just missed up the desk.', 'start': 8364.915, 'duration': 2.16}, {'end': 8370.616, 'text': 'We should create the description like that.', 'start': 8367.335, 'duration': 3.281}, {'end': 8372.576, 'text': 'Okay So everything works great.', 'start': 8371.356, 'duration': 1.22}, {'end': 8381.938, 'text': 'And I will go by saying db.session.add and I will add i1 and I will now use commit.', 'start': 8373.137, 'duration': 8.801}, {'end': 8383.839, 'text': 'So we will commit our changes.', 'start': 8382.218, 'duration': 1.621}, {'end': 8386.779, 'text': "Now let's repeat ourselves with another item.", 'start': 8384.339, 'duration': 2.44}, {'end': 8389.2, 'text': 'So I will clean the screen here quickly.', 'start': 8386.839, 'duration': 2.361}, {'end': 8393.784, 'text': 'And I can load the previous comments by using the arrow signs.', 'start': 8390.862, 'duration': 2.922}, {'end': 8396.506, 'text': 'So I can basically change this to I2.', 'start': 8394.264, 'duration': 2.242}, {'end': 8400.088, 'text': 'And this to laptop.', 'start': 8397.286, 'duration': 2.802}, {'end': 8403.07, 'text': 'And I will change the description to description2.', 'start': 8400.729, 'duration': 2.341}, {'end': 8407.613, 'text': 'And the barcode here will be a little bit different.', 'start': 8404.051, 'duration': 3.562}, {'end': 8410.735, 'text': 'And the price will be 1000 that time.', 'start': 8408.234, 'duration': 2.501}, {'end': 8415.438, 'text': 'And we can repeat ourselves again by saying tb.session.add and .commit.', 'start': 8411.236, 'duration': 4.202}, {'end': 8415.799, 'text': 'Like that.', 'start': 8415.458, 'duration': 0.341}, {'end': 8424.443, 'text': 'Okay, so now we have two items stored inside our database.', 'start': 8420.982, 'duration': 3.461}, {'end': 8428.724, 'text': 'So we can verify this by saying query.all.', 'start': 8424.523, 'duration': 4.201}, {'end': 8433.105, 'text': "And now let's try to assign an ownership to the iPhone 10 item.", 'start': 8428.884, 'duration': 4.221}, {'end': 8437.726, 'text': 'So we have to go and filter this specific iPhone 10 object.', 'start': 8433.165, 'duration': 4.561}, {'end': 8443.487, 'text': 'And we can do that by saying item.query.filter underscore buy.', 'start': 8438.086, 'duration': 5.401}, {'end': 8448.428, 'text': 'And I can filter by name equals to iPhone10.', 'start': 8443.927, 'duration': 4.501}, {'end': 8451.335, 'text': '10 like that.', 'start': 8449.914, 'duration': 1.421}, {'end': 8455.279, 'text': 'Okay, so it also makes sense to assign this into a new variable.', 'start': 8451.916, 'duration': 3.363}, {'end': 8459.402, 'text': 'So I will go ahead and with item one, I will assign it.', 'start': 8455.359, 'duration': 4.043}, {'end': 8464.466, 'text': 'And now if I access item one, then you can see that it returns us a base query.', 'start': 8459.802, 'duration': 4.664}, {'end': 8471.521, 'text': 'And now we can basically use this first method to grab the specific object itself.', 'start': 8464.846, 'duration': 6.675}, {'end': 8477.884, 'text': 'so now i have the item1 object in here and now i want to test up the results.', 'start': 8471.521, 'duration': 6.363}, {'end': 8485.587, 'text': "if i try to access the attribute of owner and now you can see that it returns us nothing because it doesn't have an owner.", 'start': 8477.884, 'duration': 7.703}, {'end': 8487.108, 'text': 'now to continue from here,', 'start': 8485.587, 'duration': 1.521}, {'end': 8499.814, 'text': 'i can basically say that i want to assign the owner of item1 to the specific object of the user that we have just created previously with the username of jsc.', 'start': 8487.108, 'duration': 12.706}, {'end': 8510.624, 'text': 'so it will look like something like the following so it will be item1.owner and this will be equal to user.query.filter, underscore by,', 'start': 8499.814, 'duration': 10.81}, {'end': 8516.169, 'text': 'and i want to filter by the username equals to jsc and if you remember,', 'start': 8510.624, 'duration': 5.545}, {'end': 8526.257, 'text': 'this entire statement here returns us a base object and we have to access the actual object by saying dot first and as i have done that,', 'start': 8516.169, 'duration': 10.088}, {'end': 8538.925, 'text': 'then i can continue on to db.session.commit and i can assign the item one and now, sorry, i should have type in here add great,', 'start': 8526.257, 'duration': 12.668}, {'end': 8547.498, 'text': 'and then i should have continue to commit Now, as I have done that, then we can see several errors over here.', 'start': 8538.925, 'duration': 8.573}, {'end': 8556.253, 'text': 'Now I can see that we have this update item set owner where item.id equals to a question mark.', 'start': 8548.279, 'duration': 7.974}, {'end': 8563.38, 'text': "Now I have a feeling that I know why this happened and it's sometimes that always may confuse every one of us.", 'start': 8556.897, 'duration': 6.483}, {'end': 8574.606, 'text': 'And the point is we have to understand that the only way that we can assign the attribute of owner is by specifying the ID of the user.', 'start': 8563.88, 'duration': 10.726}, {'end': 8580.709, 'text': 'So if you remember our foreign key is only going to accept the attribute of ID.', 'start': 8574.946, 'duration': 5.763}, {'end': 8584.991, 'text': 'So this is why we have done a great job by filtering the specific user.', 'start': 8581.129, 'duration': 3.862}, {'end': 8588.494, 'text': 'But only we had to give it the attribute of ID.', 'start': 8585.431, 'duration': 3.063}, {'end': 8590.115, 'text': "So let's go ahead and fix that.", 'start': 8588.574, 'duration': 1.541}, {'end': 8593.337, 'text': "So before everything, let's clean the screen for a minute.", 'start': 8590.255, 'duration': 3.082}, {'end': 8596.18, 'text': 'So it will be CLS inside OS dot system.', 'start': 8593.718, 'duration': 2.462}, {'end': 8602.424, 'text': 'And before I actually take different changes inside our item one, we have to execute this command,', 'start': 8596.66, 'duration': 5.764}, {'end': 8606.668, 'text': 'which is going to look like db dot session dot rollback.', 'start': 8602.424, 'duration': 4.244}, {'end': 8610.211, 'text': 'so we can roll back our previous changes and commits.', 'start': 8607.048, 'duration': 3.163}, {'end': 8615.376, 'text': 'And once I execute that, if I did not receive any errors, then it should be fine.', 'start': 8610.671, 'duration': 4.705}, {'end': 8620.601, 'text': 'And now I will just type in the exact same command that we wrote previously.', 'start': 8615.716, 'duration': 4.885}, {'end': 8628.887, 'text': 'So it will be item one dot owner, and it will be user dot query dot filter underscore by,', 'start': 8620.681, 'duration': 8.206}, {'end': 8643.558, 'text': 'and we will filter by jsc and after the dot first in here we have to give it the attribute of id and once i have done that then i can basically add it to our session,', 'start': 8628.887, 'duration': 14.671}, {'end': 8653.047, 'text': 'which is clean, because we have rolled back the previous commits and now we can try to execute the commit and this should work.', 'start': 8643.558, 'duration': 9.489}, {'end': 8662.135, 'text': 'so if i was to go ahead and see the owner, then you can see that it returns us one and the reason it returns us one.', 'start': 8653.047, 'duration': 9.088}, {'end': 8666.819, 'text': 'it is basically because this is the foreign key of the owned user.', 'start': 8662.135, 'duration': 4.684}, {'end': 8671.282, 'text': 'now we can also test this by filtering the item specifically.', 'start': 8666.819, 'duration': 4.463}, {'end': 8683.263, 'text': 'so we can go with i equals to item dot query dot filter underscore by, and we want to filter by name equals to iphone 10 like that,', 'start': 8671.282, 'duration': 11.981}, {'end': 8688.665, 'text': 'and now we can basically try to see the back reference of the item that i talked about.', 'start': 8683.263, 'duration': 5.402}], 'summary': 'Demonstrates setting up back reference, lazy loading, and creating relationships between user and item models in a database using python and sqlalchemy.', 'duration': 689.596, 'max_score': 7999.069, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo7999069.jpg'}, {'end': 8183.925, 'src': 'embed', 'start': 8150.151, 'weight': 5, 'content': [{'end': 8158.337, 'text': 'And this is related to the each unique row that is going to be stored in that ID.', 'start': 8150.151, 'duration': 8.186}, {'end': 8163.66, 'text': 'So it is quite important to write here user dot ID in lowercase.', 'start': 8158.397, 'duration': 5.263}, {'end': 8166.082, 'text': "Okay, so now I'm back at my terminal.", 'start': 8163.94, 'duration': 2.142}, {'end': 8170.565, 'text': 'And I like to create all the tables from scratch inside our database.', 'start': 8166.502, 'duration': 4.063}, {'end': 8172.346, 'text': 'So we will go with Python.', 'start': 8170.625, 'duration': 1.721}, {'end': 8176.589, 'text': 'And we will use here from market dot modules.', 'start': 8172.846, 'duration': 3.743}, {'end': 8179.062, 'text': 'import DB.', 'start': 8177.961, 'duration': 1.101}, {'end': 8183.925, 'text': 'And then we can basically say DB dot drop all.', 'start': 8179.602, 'duration': 4.323}], 'summary': 'Creating tables in database using python, dropping all tables', 'duration': 33.774, 'max_score': 8150.151, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo8150151.jpg'}, {'end': 8229.984, 'src': 'embed', 'start': 8205.005, 'weight': 4, 'content': [{'end': 8213.674, 'text': 'basically, you could also execute create underscore all, but i just wanted to show you that there is the option of drop underscore all as well.', 'start': 8205.005, 'duration': 8.669}, {'end': 8220.08, 'text': "so now, if i go ahead and create everything, Then if I don't receive errors, then it means that everything looks great.", 'start': 8213.674, 'duration': 6.406}, {'end': 8223.821, 'text': 'Now we can continue by importing the models.', 'start': 8220.559, 'duration': 3.262}, {'end': 8229.984, 'text': 'So we will say import user and item again from our market.modules.', 'start': 8223.901, 'duration': 6.083}], 'summary': 'Demonstrating the option to drop all and import user and item from market.modules.', 'duration': 24.979, 'max_score': 8205.005, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo8205004.jpg'}, {'end': 8403.07, 'src': 'embed', 'start': 8371.356, 'weight': 3, 'content': [{'end': 8372.576, 'text': 'Okay So everything works great.', 'start': 8371.356, 'duration': 1.22}, {'end': 8381.938, 'text': 'And I will go by saying db.session.add and I will add i1 and I will now use commit.', 'start': 8373.137, 'duration': 8.801}, {'end': 8383.839, 'text': 'So we will commit our changes.', 'start': 8382.218, 'duration': 1.621}, {'end': 8386.779, 'text': "Now let's repeat ourselves with another item.", 'start': 8384.339, 'duration': 2.44}, {'end': 8389.2, 'text': 'So I will clean the screen here quickly.', 'start': 8386.839, 'duration': 2.361}, {'end': 8393.784, 'text': 'And I can load the previous comments by using the arrow signs.', 'start': 8390.862, 'duration': 2.922}, {'end': 8396.506, 'text': 'So I can basically change this to I2.', 'start': 8394.264, 'duration': 2.242}, {'end': 8400.088, 'text': 'And this to laptop.', 'start': 8397.286, 'duration': 2.802}, {'end': 8403.07, 'text': 'And I will change the description to description2.', 'start': 8400.729, 'duration': 2.341}], 'summary': 'Adding i1 to db and committing changes, then adding i2 and updating description.', 'duration': 31.714, 'max_score': 8371.356, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo8371356.jpg'}, {'end': 8574.606, 'src': 'embed', 'start': 8548.279, 'weight': 7, 'content': [{'end': 8556.253, 'text': 'Now I can see that we have this update item set owner where item.id equals to a question mark.', 'start': 8548.279, 'duration': 7.974}, {'end': 8563.38, 'text': "Now I have a feeling that I know why this happened and it's sometimes that always may confuse every one of us.", 'start': 8556.897, 'duration': 6.483}, {'end': 8574.606, 'text': 'And the point is we have to understand that the only way that we can assign the attribute of owner is by specifying the ID of the user.', 'start': 8563.88, 'duration': 10.726}], 'summary': 'Update item set owner using user id.', 'duration': 26.327, 'max_score': 8548.279, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo8548279.jpg'}, {'end': 8683.263, 'src': 'embed', 'start': 8653.047, 'weight': 0, 'content': [{'end': 8662.135, 'text': 'so if i was to go ahead and see the owner, then you can see that it returns us one and the reason it returns us one.', 'start': 8653.047, 'duration': 9.088}, {'end': 8666.819, 'text': 'it is basically because this is the foreign key of the owned user.', 'start': 8662.135, 'duration': 4.684}, {'end': 8671.282, 'text': 'now we can also test this by filtering the item specifically.', 'start': 8666.819, 'duration': 4.463}, {'end': 8683.263, 'text': 'so we can go with i equals to item dot query dot filter underscore by, and we want to filter by name equals to iphone 10 like that,', 'start': 8671.282, 'duration': 11.981}], 'summary': "The query returns one item, with 'iphone 10' as the name.", 'duration': 30.216, 'max_score': 8653.047, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo8653047.jpg'}], 'start': 7794.789, 'title': 'Database setup and testing', 'summary': 'Covers setting up user model with password hash and budget attribute, creating database relationships between user and item models, and testing the database relationships and ownership. it includes details such as password hash of 60 characters, non-unique budget attribute with a default value of 1000, specifying back references, foreign keys, lazy loading, and testing the creation of items and assigning ownership through database relationships.', 'chapters': [{'end': 7915.745, 'start': 7794.789, 'title': 'Setting up user model with password hash and budget', 'summary': 'Describes setting up the user model with a password hash of 60 characters and a non-unique budget attribute with a default value of 1000, for implementing a budget system for users.', 'duration': 120.956, 'highlights': ['Setting up password field with a 60-character hash for the mostly used hashing algorithm in Flask, ensuring data security and integrity.', 'Defining a budget attribute for users with a non-unique constraint and a default value of 1000, enabling the implementation of a budget system for the users.', 'Describing the process of setting up the user model with specific attributes, such as password hash and budget, to ensure secure and structured user data.']}, {'end': 8320.892, 'start': 7915.925, 'title': 'Database relationship and model setup', 'summary': 'Covers setting up database relationships between user and item models using sqlalchemy in python, including specifying back references, foreign keys, and lazy loading, and creating and testing the tables.', 'duration': 404.967, 'highlights': ['The chapter covers setting up database relationships between user and item models using SQLAlchemy in Python, including specifying back references, foreign keys, and lazy loading, and creating and testing the tables.', "The back reference allows accessing items owned by a user and vice versa, enabling the retrieval of specific item owners, while lazy loading optimizes object retrieval by specifying 'lazy=True' to prevent grabbing all objects at once.", "The process involves creating foreign keys to relate to the primary key of the user model, ensuring each row is uniquely stored in the specified ID, and using 'db.relationship' to describe the relationship between the user and item models.", 'The steps include dropping all tables, recreating them, and testing them for errors, and adding a new user to the database, ensuring the proper storage and retrieval of user information.']}, {'end': 8714.444, 'start': 8321.312, 'title': 'Testing database relationships and ownership', 'summary': 'Explains testing the creation of items and assigning ownership through database relationships, involving adding, filtering, and committing data, while emphasizing the importance of specifying the id when assigning attributes.', 'duration': 393.132, 'highlights': ["The process involves creating items such as 'iPhone 10' and 'laptop' and setting their respective descriptions, barcodes, and prices, with the latter being set to $1000.", "Demonstrates adding items to the database, checking the total number of stored items, and filtering items by name, such as 'iPhone 10'.", "Illustrates the assignment of ownership to the 'iPhone 10' item by filtering the specific object and linking it to the user 'jsc' through their ID, culminating in successful ownership assignment and validation.", 'Highlights the importance of specifying the ID of the user when assigning attributes, emphasizing the significance of understanding foreign key constraints and the potential errors that may arise.', "Emphasizes the need to roll back previous changes in case of errors and reiterates the process of specifying the user's ID when assigning ownership attributes, culminating in successful validation of ownership and back-reference retrieval."]}], 'duration': 919.655, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo7794789.jpg', 'highlights': ['Setting up password field with a 60-character hash for data security.', 'Defining a budget attribute for users with a default value of 1000.', 'Creating database relationships between user and item models using SQLAlchemy.', 'Specifying back references, foreign keys, and lazy loading for optimized object retrieval.', "Creating items such as 'iPhone 10' and 'laptop' with descriptions, barcodes, and prices.", 'Adding items to the database, checking total number of stored items, and filtering items by name.', "Illustrating the assignment of ownership to the 'iPhone 10' item and emphasizing the importance of specifying the user's ID.", 'Emphasizing the need to roll back previous changes in case of errors.']}, {'end': 11589.239, 'segs': [{'end': 8869.03, 'src': 'embed', 'start': 8843.671, 'weight': 6, 'content': [{'end': 8848.517, 'text': "So anyway, just write this command as well for safety and let's continue from here.", 'start': 8843.671, 'duration': 4.846}, {'end': 8855.766, 'text': 'Okay, so as I said previously, the forms are going to be a quite different element in our flask application.', 'start': 8848.777, 'duration': 6.989}, {'end': 8862.348, 'text': 'So this is why it totally makes sense to create a Python file that we will name it forms.py,', 'start': 8856.226, 'duration': 6.122}, {'end': 8867.45, 'text': 'and then each form that we are going to create for some situation will be stored there.', 'start': 8862.348, 'duration': 5.102}, {'end': 8869.03, 'text': "So let's go ahead and do that.", 'start': 8867.63, 'duration': 1.4}], 'summary': 'Creating a forms.py file to store different forms for flask application.', 'duration': 25.359, 'max_score': 8843.671, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo8843671.jpg'}, {'end': 9432.5, 'src': 'embed', 'start': 9404.978, 'weight': 13, 'content': [{'end': 9408.759, 'text': 'and that is simply because we change our request type to our clients.', 'start': 9404.978, 'duration': 3.781}, {'end': 9414.545, 'text': 'So until now, we were able to display HTML pages for our clients.', 'start': 9409.159, 'duration': 5.386}, {'end': 9423.854, 'text': 'But when it comes to forms, now our clients are going to be able to submit actual information towards our database.', 'start': 9414.945, 'duration': 8.909}, {'end': 9427.718, 'text': 'So this is a quite different action that must be secure enough.', 'start': 9423.914, 'duration': 3.804}, {'end': 9432.5, 'text': 'So this is why we have to create a secret key for our flask application.', 'start': 9428.058, 'duration': 4.442}], 'summary': 'Clients can now submit forms, requiring secure secret key for flask application.', 'duration': 27.522, 'max_score': 9404.978, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo9404978.jpg'}, {'end': 9510.177, 'src': 'embed', 'start': 9459.932, 'weight': 4, 'content': [{'end': 9463.034, 'text': 'And then we can provide here the value of 12.', 'start': 9459.932, 'duration': 3.102}, {'end': 9465.675, 'text': 'So it will be by the value of 12 bytes.', 'start': 9463.034, 'duration': 2.641}, {'end': 9471.178, 'text': 'And then we can basically go ahead and convert this to hexadecimal values.', 'start': 9466.075, 'duration': 5.103}, {'end': 9478.522, 'text': 'And then the value that will be receiving back will be the secret key that we auto generated for our application.', 'start': 9471.558, 'duration': 6.964}, {'end': 9486.127, 'text': 'Now, there is nothing wrong with going ahead and generate more secret keys, but just make sure that if you use one,', 'start': 9479.022, 'duration': 7.105}, {'end': 9489.41, 'text': 'then stick to it throughout the development of that application.', 'start': 9486.127, 'duration': 3.283}, {'end': 9499.277, 'text': "So let's grab this secret key and go back to our Python and navigate inside our init.py.", 'start': 9489.91, 'duration': 9.367}, {'end': 9502.94, 'text': 'And then here we have to write in some new configuration.', 'start': 9499.617, 'duration': 3.323}, {'end': 9505.782, 'text': 'So it will be app.config.', 'start': 9503.02, 'duration': 2.762}, {'end': 9510.177, 'text': 'And then our key here will be secret underscore key.', 'start': 9506.334, 'duration': 3.843}], 'summary': 'Generating a secret key with a value of 12 bytes and converting it to hexadecimal format for application use.', 'duration': 50.245, 'max_score': 9459.932, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo9459932.jpg'}, {'end': 9804.038, 'src': 'embed', 'start': 9772.879, 'weight': 0, 'content': [{'end': 9787.772, 'text': 'So I will say form.username.label And I will open and close the parentheses here And below that we can say form.username And I can open the parentheses and close them up here again.', 'start': 9772.879, 'duration': 14.893}, {'end': 9798.096, 'text': 'Now what is so special with that flask forms is that this statement is going to accept attributes like in real HTML code.', 'start': 9788.312, 'duration': 9.784}, {'end': 9804.038, 'text': 'So we could say here class and then we could basically give it a bootstrap class.', 'start': 9798.456, 'duration': 5.582}], 'summary': 'Using flask forms to accept html attributes like class for bootstrap styling.', 'duration': 31.159, 'max_score': 9772.879, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo9772879.jpg'}, {'end': 10067.421, 'src': 'embed', 'start': 10016.928, 'weight': 3, 'content': [{'end': 10021.891, 'text': 'We can change this to password two and this will be confirmed password.', 'start': 10016.928, 'duration': 4.963}, {'end': 10025.574, 'text': 'Now to test the results of that, we can refresh it.', 'start': 10022.352, 'duration': 3.222}, {'end': 10035.685, 'text': 'You can see that we receive an error and that is fine because we defined the email field as email underscore address.', 'start': 10026.977, 'duration': 8.708}, {'end': 10037.507, 'text': "So let's fix that quickly.", 'start': 10035.745, 'duration': 1.762}, {'end': 10042.632, 'text': 'So it will be underscore address and underscore address as well.', 'start': 10038.087, 'duration': 4.545}, {'end': 10049.274, 'text': 'Now you can see that I trend to not cut the arrows that I received throughout this video,', 'start': 10043.052, 'duration': 6.222}, {'end': 10059.998, 'text': 'sometimes because I really want you to be aware of the possible arrows that you can meet throughout the process of writing any HTML code or any Python related code.', 'start': 10049.274, 'duration': 10.724}, {'end': 10064.9, 'text': "So this is the reason that I'm okay with the arrows and handling them on the fly.", 'start': 10060.039, 'duration': 4.861}, {'end': 10067.421, 'text': 'Okay, so I will refresh that out.', 'start': 10065.381, 'duration': 2.04}], 'summary': 'Fixing email field as email_address to resolve errors in html code and python related code', 'duration': 50.493, 'max_score': 10016.928, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo10016928.jpg'}, {'end': 10584.33, 'src': 'embed', 'start': 10560.976, 'weight': 1, 'content': [{'end': 10567.96, 'text': 'And once we have done that, then we probably want to redirect our users to a different page.', 'start': 10560.976, 'duration': 6.984}, {'end': 10573.143, 'text': 'Now it quite makes sense because now they are registered to the website.', 'start': 10568.501, 'duration': 4.642}, {'end': 10578.687, 'text': 'And now we can show the user the items that are available on the market.', 'start': 10573.564, 'duration': 5.123}, {'end': 10584.33, 'text': 'So I will use the built-in redirect function that the flask package offers us.', 'start': 10579.167, 'duration': 5.163}], 'summary': 'Redirect users to a different page after registration using flask package.', 'duration': 23.354, 'max_score': 10560.976, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo10560976.jpg'}, {'end': 11589.239, 'src': 'embed', 'start': 11535.919, 'weight': 2, 'content': [{'end': 11540.744, 'text': 'Now, if we want to test multiple validations that are going to fail,', 'start': 11535.919, 'duration': 4.825}, {'end': 11555.918, 'text': 'then we can basically try to mismatch the email in here by writing some numbers and we can unmatch the password and confirm password and we can try to click on create account and now we can see multiple arrows.', 'start': 11540.744, 'duration': 15.174}, {'end': 11565.467, 'text': 'So we have the there was an error creating a user with this message and we also have it for the message here as well.', 'start': 11555.998, 'duration': 9.469}, {'end': 11570.542, 'text': 'And I think we saw this twice because I was looking up here, so sorry.', 'start': 11566.718, 'duration': 3.824}, {'end': 11572.503, 'text': 'And there should be three arrows.', 'start': 11571.142, 'duration': 1.361}, {'end': 11576.587, 'text': 'So the third is that field must be equal to password one.', 'start': 11572.583, 'duration': 4.004}, {'end': 11580.23, 'text': 'And we also see that invalid email address.', 'start': 11577.148, 'duration': 3.082}, {'end': 11589.239, 'text': 'And I think that this explains that our validations are working perfect because we saw the results as expected.', 'start': 11580.831, 'duration': 8.408}], 'summary': 'Multiple validation failures occurred, including mismatched email and passwords, leading to three error messages and confirmation that validations are working as expected.', 'duration': 53.32, 'max_score': 11535.919, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo11535919.jpg'}], 'start': 8714.444, 'title': 'Creating secure registration forms', 'summary': 'Covers creating registration forms in flask, using flask-wtf and wtforms packages, emphasizing the importance of a secret key for security, and focuses on html, request methods, error handling, and user validation.', 'chapters': [{'end': 9486.127, 'start': 8714.444, 'title': 'Creating secure registration forms', 'summary': 'Covers the creation of a registration form in flask, including the use of flask-wtf and wtforms packages, and the importance of creating a secret key for security, aiming to enhance website functionality and user experience.', 'duration': 771.683, 'highlights': ["Creating a registration form using Flask-WTF and WTForms packages The chapter discusses the process of creating a registration form in Flask using the Flask-WTF and WTForms packages, aiming to enhance the website's functionality and user experience.", 'Importance of creating a secret key for security Emphasizes the importance of generating a secret key for the Flask application to ensure security when submitting information through forms, enhancing the security measures of the website.', 'Customizing a nice-looking HTML page for user registration Describes the process of customizing an HTML form to allow users to register on the website, aiming to improve the user experience and make the registration process visually appealing.']}, {'end': 10042.632, 'start': 9486.127, 'title': 'Configuring form and navigation', 'summary': 'Covers configuring a secret key, displaying a registration form, customizing the navigation bar, and styling form fields in a flask application, with a focus on html and request methods, including get and post.', 'duration': 556.505, 'highlights': ['Configuring a secret key in the Python Flask application The secret key is configured in the Python Flask application to enhance security and protect sensitive information.', 'Displaying the registration form and testing the functionality The registration form is displayed successfully in the web application, allowing users to input information for registration.', 'Customizing the navigation bar to link to the register page The navigation bar is customized to include a link to the register page, utilizing the URL_for built-in function for routing.', "Styling form fields and configuring request methods Form fields are styled using HTML syntax, and the post request method is utilized to affect the website's database, enhancing user experience and security."]}, {'end': 10822.546, 'start': 10043.052, 'title': 'Html and python code tutorial', 'summary': 'Covers the process of writing html and python code, including handling errors, adding images and form fields, centralizing objects, configuring the behind-the-scenes actions, and protecting from cross-site request forgery, emphasizing the importance of validations and conditional checks.', 'duration': 779.494, 'highlights': ['The chapter covers the process of writing HTML and Python code The tutorial focuses on writing code in HTML and Python.', "Configuring the behind-the-scenes actions The tutorial explains how to handle the actions after clicking the 'create account' button by writing Python code in the routes.py file.", 'Protecting from cross-site request forgery The tutorial emphasizes the importance of protecting the website from cross-site request forgery by adding a hidden tag in the HTML form.', 'Handling errors and adding images and form fields The tutorial highlights the process of handling errors, adding images, and form fields to the HTML code.', 'Importance of validations and conditional checks The tutorial emphasizes the importance of validations and conditional checks before submitting changes into the database.']}, {'end': 11589.239, 'start': 10822.546, 'title': 'Website validation and user creation', 'summary': "Details the process of testing the website's registration functionality, implementing user validations, and handling validation errors, resulting in the successful creation of user accounts with proper validation checks.", 'duration': 766.693, 'highlights': ['Implemented user validations for the username and password fields, ensuring username length between 2 and 30 characters and password length of at least 6 characters, resulting in improved security and data integrity. Username length (2-30 characters), Password length (minimum 6 characters)', "Utilized Flask's built-in validation package to check for email format and ensure the presence of data in each field, enhancing the accuracy and validity of user-provided information. Verified email format, Ensured data presence in fields", 'Demonstrated error handling by checking form errors and iterating over validation messages, providing insights into handling validation failures and printing relevant error messages for debugging. Iterated over validation error messages, Demonstrated error handling']}], 'duration': 2874.795, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo8714444.jpg', 'highlights': ['Creating a registration form using Flask-WTF and WTForms packages', 'Importance of creating a secret key for security', 'Customizing a nice-looking HTML page for user registration', 'Configuring a secret key in the Python Flask application', 'Displaying the registration form and testing the functionality', 'Customizing the navigation bar to link to the register page', 'Styling form fields and configuring request methods', 'The chapter covers the process of writing HTML and Python code', 'Configuring the behind-the-scenes actions', 'Protecting from cross-site request forgery', 'Handling errors and adding images and form fields', 'Importance of validations and conditional checks', 'Implemented user validations for the username and password fields, ensuring username length between 2 and 30 characters and password length of at least 6 characters', "Utilized Flask's built-in validation package to check for email format and ensure the presence of data in each field", 'Demonstrated error handling by checking form errors and iterating over validation messages']}, {'end': 12462.237, 'segs': [{'end': 11689.505, 'src': 'embed', 'start': 11663.619, 'weight': 1, 'content': [{'end': 11681.483, 'text': 'so we are importing that built-in function and the way that we are going to do that is by first flashing some messages and then we are going to go inside our HTML templates and we are going to use a built-in function that is called get flashed messages.', 'start': 11663.619, 'duration': 17.864}, {'end': 11684.864, 'text': 'and what is so beautiful with the get flashed messages?', 'start': 11681.483, 'duration': 3.381}, {'end': 11689.505, 'text': 'it will allow us to gather all the flashed messages, as the function says.', 'start': 11684.864, 'duration': 4.641}], 'summary': 'Using the get flashed messages function to gather all flashed messages in html templates.', 'duration': 25.886, 'max_score': 11663.619, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo11663619.jpg'}, {'end': 11824.903, 'src': 'embed', 'start': 11797.291, 'weight': 4, 'content': [{'end': 11802.233, 'text': 'we are going to add certain categories for the different messages that we want to display.', 'start': 11797.291, 'duration': 4.942}, {'end': 11807.555, 'text': 'So the important point here is to understand that not only we can display some errors,', 'start': 11802.613, 'duration': 4.942}, {'end': 11810.816, 'text': 'but we can also display regular information or success messages.', 'start': 11807.555, 'duration': 3.261}, {'end': 11814.277, 'text': 'And we are going to see how we are going to do that in a few minutes.', 'start': 11811.176, 'duration': 3.101}, {'end': 11824.903, 'text': 'now i just realized that i implemented the variable block and with the get flashed messages it expects for the block code.', 'start': 11814.677, 'duration': 10.226}], 'summary': 'Implementing message categories for display, including errors, information, and success.', 'duration': 27.612, 'max_score': 11797.291, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo11797291.jpg'}, {'end': 12217.182, 'src': 'embed', 'start': 12190.184, 'weight': 0, 'content': [{'end': 12195.869, 'text': 'And that is responsible to display a red looking message.', 'start': 12190.184, 'duration': 5.685}, {'end': 12201.534, 'text': 'So our users could understand that this is basically an error and something went wrong.', 'start': 12196.029, 'duration': 5.505}, {'end': 12208.738, 'text': "And inside those div tags, I'm going to continue on by typing here button.", 'start': 12202.094, 'duration': 6.644}, {'end': 12217.182, 'text': 'So this is going to be like a wide paragraph where the users could have the option to close the different alerts.', 'start': 12209.018, 'duration': 8.164}], 'summary': 'Display red error message to help users understand and close alerts.', 'duration': 26.998, 'max_score': 12190.184, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo12190184.jpg'}, {'end': 12332.757, 'src': 'embed', 'start': 12305.464, 'weight': 2, 'content': [{'end': 12308.766, 'text': 'This is the exact symbol that I want to refer to.', 'start': 12305.464, 'duration': 3.302}, {'end': 12314.629, 'text': 'So I can just say times and then colon semicolon like that.', 'start': 12309.146, 'duration': 5.483}, {'end': 12320.612, 'text': "So once I have done that, let's see the results and let's see the logic behind this HTML code.", 'start': 12315.109, 'duration': 5.503}, {'end': 12327.036, 'text': "OK, so let's go here and let's actually put the pie charm in the left pane and.", 'start': 12320.712, 'duration': 6.324}, {'end': 12330.056, 'text': 'our website in here.', 'start': 12327.996, 'duration': 2.06}, {'end': 12332.757, 'text': 'so it will totally make sense to see those together.', 'start': 12330.056, 'duration': 2.701}], 'summary': 'Referring to a specific symbol, discussing html code and website layout.', 'duration': 27.293, 'max_score': 12305.464, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo12305464.jpg'}, {'end': 12437.253, 'src': 'embed', 'start': 12409.239, 'weight': 5, 'content': [{'end': 12423.184, 'text': 'so I will just type in here some random characters and click on create account and then you can see that we see a nice looking error and our clients could really understand that we have something wrong.', 'start': 12409.239, 'duration': 13.945}, {'end': 12429.327, 'text': 'and we also have the option to close this button by clicking on the X right there.', 'start': 12423.184, 'duration': 6.143}, {'end': 12437.253, 'text': 'Now the attribute of data dismiss and area label and area hidden equals true,', 'start': 12429.587, 'duration': 7.666}], 'summary': 'Demonstration of generating an error message with attributes for client understanding.', 'duration': 28.014, 'max_score': 12409.239, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo12409239.jpg'}], 'start': 11589.759, 'title': 'Flashing messages in flask', 'summary': "Covers implementing and customizing flashing messages in flask, using 'flash' and 'get flashed messages' functions to display validation errors, and customizing message categories and visual styles with python, html, and bootstrap.", 'chapters': [{'end': 11950.97, 'start': 11589.759, 'title': 'Flashing messages in flask', 'summary': "Discusses the implementation of flashing messages in flask to display validation errors on the website, utilizing the built-in function 'flash' and 'get flashed messages' in html templates.", 'duration': 361.211, 'highlights': ["Flask's built-in function 'flash' allows displaying information inside HTML templates, replacing the need for displaying errors in the terminal of the web server. Flask provides a built-in function called 'flash' to display information inside HTML templates, replacing the previous method of displaying errors in the web server's terminal.", "The 'get flashed messages' function enables gathering all flashed messages, providing the ability to display various messages, including errors, regular information, or success messages. The 'get flashed messages' function allows gathering all flashed messages, providing the ability to display various messages, including errors, regular information, or success messages, enhancing user interaction.", 'Implementing context managers using Jinja syntax for displaying flashed messages in the base.html template allows for consistent message display across all templates. Implementing context managers using Jinja syntax in the base.html template allows consistent display of flashed messages across all templates, ensuring a uniform user experience.']}, {'end': 12462.237, 'start': 11951.19, 'title': 'Flashed messages customization', 'summary': 'Discusses customizing flashed messages in a web application using python, html, and bootstrap, demonstrating how to display different categories of messages and how to create a visually appealing message display with the x close button.', 'duration': 511.047, 'highlights': ['The tutorial demonstrates how to customize flashed messages to display different categories of messages, such as error, information, or success messages, to provide a better user experience. The tutorial illustrates the process of assigning categories to flashed messages in Python and using Bootstrap classes to create visually distinct messages for different categories.', 'The tutorial showcases the use of HTML and Bootstrap classes to create visually appealing flashed messages, including the addition of an X close button for user interaction. The tutorial explains the use of div tags, alert classes, and button attributes from Bootstrap to create visually appealing flashed messages, allowing users to close the messages using an X button.', 'The chapter emphasizes the importance of providing a visually distinct and user-friendly display for flashed messages to enhance the user experience. The chapter underscores the significance of designing visually distinct flashed messages to convey different message categories and enhance user interaction and understanding.']}], 'duration': 872.478, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo11589759.jpg', 'highlights': ["Flask's 'flash' function replaces displaying errors in the web server's terminal.", "The 'get flashed messages' function allows displaying various messages, enhancing user interaction.", 'Implementing context managers using Jinja syntax ensures consistent display of flashed messages across all templates.', 'Customizing flashed messages to display different categories enhances user experience.', 'Using Bootstrap classes creates visually distinct messages for different categories.', 'The tutorial emphasizes the importance of visually distinct flashed messages to enhance user experience.']}, {'end': 15525.462, 'segs': [{'end': 13348.355, 'src': 'embed', 'start': 13322.489, 'weight': 3, 'content': [{'end': 13330.932, 'text': 'And in here, we need to initialize this bcrypt library, I mean an instance of a big crypt class inside that library.', 'start': 13322.489, 'duration': 8.443}, {'end': 13338.393, 'text': 'So it will be from flask underscore B crypt, import B crypt like that.', 'start': 13331.352, 'duration': 7.041}, {'end': 13343.374, 'text': 'And I just realized that we forgot to delete this vendor template from here.', 'start': 13338.833, 'duration': 4.541}, {'end': 13345.234, 'text': "So let's go ahead and do that.", 'start': 13343.814, 'duration': 1.42}, {'end': 13348.355, 'text': "And down here, I'm going to create an instance of that.", 'start': 13345.534, 'duration': 2.821}], 'summary': 'Initializing bcrypt library, deleting vendor template, and creating instance.', 'duration': 25.866, 'max_score': 13322.489, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo13322489.jpg'}, {'end': 14530.866, 'src': 'embed', 'start': 14504.246, 'weight': 2, 'content': [{'end': 14511.107, 'text': 'So if you remember, we used to call this conditional if form validate on submit.', 'start': 14504.246, 'duration': 6.861}, {'end': 14515.788, 'text': 'And then if this conditional hits true, then we are going to take several actions.', 'start': 14511.487, 'duration': 4.301}, {'end': 14518.769, 'text': 'So it might be a great idea to start with that.', 'start': 14516.308, 'duration': 2.461}, {'end': 14523.81, 'text': 'Okay, so I will say in our login page, so we will zoom in here.', 'start': 14518.909, 'duration': 4.901}, {'end': 14530.866, 'text': 'And we will say if form that validate on submit.', 'start': 14524.33, 'duration': 6.536}], 'summary': "The conditional 'if form validate on submit' is used to trigger actions on the login page.", 'duration': 26.62, 'max_score': 14504.246, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo14504246.jpg'}, {'end': 14822.221, 'src': 'embed', 'start': 14794.086, 'weight': 1, 'content': [{'end': 14803.832, 'text': "then basically what I'm saying is execute this function and return its value back when we call the check password correction.", 'start': 14794.086, 'duration': 9.746}, {'end': 14806.774, 'text': 'So this is going to return us either true or false.', 'start': 14803.872, 'duration': 2.902}, {'end': 14813.078, 'text': 'So once we have done that, then basically we can go to our routes.py.', 'start': 14807.334, 'duration': 5.744}, {'end': 14822.221, 'text': 'Now you can remember how the attempted user is going to be stored within a user object,', 'start': 14814.179, 'duration': 8.042}], 'summary': 'Execute function to return true or false for check password correction.', 'duration': 28.135, 'max_score': 14794.086, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo14794086.jpg'}, {'end': 15442.321, 'src': 'embed', 'start': 15417.932, 'weight': 0, 'content': [{'end': 15424.954, 'text': 'So this really saves us a lot of time to really go ahead and hard code some four methods that the flask asks us to do.', 'start': 15417.932, 'duration': 7.022}, {'end': 15430.276, 'text': 'So it is enough to add it as an additional class that we want to inherit from.', 'start': 15425.334, 'duration': 4.942}, {'end': 15435.377, 'text': 'Okay, so once we have done that, then we can really go ahead and test for another time.', 'start': 15430.716, 'duration': 4.661}, {'end': 15442.321, 'text': 'If we can log in our users, So I will go to our terminal and check if our website is up and running.', 'start': 15435.797, 'duration': 6.524}], 'summary': 'Using inheritance in flask to save time and test login functionality, ensuring website is up and running.', 'duration': 24.389, 'max_score': 15417.932, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo15417932.jpg'}], 'start': 12462.438, 'title': 'User registration and login process', 'summary': 'Discusses handling user validation, updating registration form, implementing password hashing, and designing user login page in a flask web application, aiming to achieve secure and efficient user authentication and interaction.', 'chapters': [{'end': 13027.009, 'start': 12462.438, 'title': 'Handling existing user validation', 'summary': 'Discusses handling existing user validation in a registration form, demonstrating catching unique errors, implementing validation for username and email address to avoid displaying errors to users, and utilizing flask form class for executing validation functions.', 'duration': 564.571, 'highlights': ['The chapter demonstrates catching unique errors in a registration form by implementing validation for username and email address to avoid displaying errors to users.', 'It describes utilizing the Flask form class to execute validation functions for username and email address, ensuring a smooth user experience.', 'The tutorial details the process of querying the user model to check for existing usernames and email addresses, ensuring the prevention of duplicate entries in the database.', 'It highlights the importance of the naming convention for the validation functions to be executed by the Flask form class, emphasizing the significance of unique function names for specific validations.']}, {'end': 13454.036, 'start': 13028.737, 'title': 'Updating user registration form', 'summary': 'Details the process of updating the user registration form, including fixing validation errors, implementing hashed passwords for security, and installing flask bcrypt library to achieve this.', 'duration': 425.299, 'highlights': ['The chapter details the process of updating the user registration form, including fixing validation errors, implementing hashed passwords for security, and installing Flask Bcrypt library to achieve this. This encapsulates the main focus of the chapter, highlighting the key points and quantitative data.', "The error message 'username already exists, please try a different username' is shown when attempting to register with an existing username, indicating successful validation. Provides a specific example of successful validation and the corresponding error message displayed.", 'Implementing hashed passwords with Flask Bcrypt library to enhance security by storing encrypted passwords instead of plain text in the database. Details the security enhancement process and the specific library used for implementation.']}, {'end': 13737.725, 'start': 13454.496, 'title': 'Implementing password hashing in python', 'summary': 'Details the process of implementing password hashing in python using bcrypt, including creating a password property, setting up the password, using bcrypt to generate password hash, and updating the route.py to handle hash passwords, ultimately resulting in successful implementation and verification of hash passwords for a new user.', 'duration': 283.229, 'highlights': ["The process involves creating a password property, setting up the password, using Bcrypt to generate password hash, and updating the route.py to handle hash passwords, ultimately resulting in successful implementation and verification of hash passwords for a new user, with the example of creating a new user 'JSC three' with a hashed password.", "The code involves using Bcrypt to generate password hash, decoding the generated password hash, and updating the route.py to handle hash passwords, ultimately resulting in successful implementation and verification of hash passwords for a new user, with the example of creating a new user 'JSC three' with a hashed password.", "The chapter also explains the process of updating the route.py to handle hash passwords, ultimately resulting in successful implementation and verification of hash passwords for a new user, with the example of creating a new user 'JSC three' with a hashed password.", "The chapter details the process of creating a password property, setting up the password, and using Bcrypt to generate password hash, ultimately resulting in successful implementation and verification of hash passwords for a new user, with the example of creating a new user 'JSC three' with a hashed password."]}, {'end': 14077.566, 'start': 13737.805, 'title': 'User login page design', 'summary': 'Covers the design and implementation of a user login page, including creating a route, template, and form class, and ensuring proper functionality, such as rendering the page and handling form fields.', 'duration': 339.761, 'highlights': ['The chapter explains the process of creating a user login page, including designing a route, template, and form class, and ensuring proper functionality.', 'The implementation involves creating a route for the login page, setting up methods for get and post requests, and rendering the login template using render_template function.', 'A login form class is created with fields for username and password, including validation for data required, to enable user login functionality.']}, {'end': 15525.462, 'start': 14077.926, 'title': 'Flask login form implementation', 'summary': 'Details the process of implementing a login form in a flask web application, including importing the login form, customizing the html page, verifying user login information, managing the login system, and handling exceptions, aiming to provide a seamless user experience and efficient functionality.', 'duration': 1447.536, 'highlights': ['Implemented the HTML logic in the registration form, created a form HTML tag, and customized the HTML page. The chapter discusses the process of implementing the HTML logic in the registration form, creating a form HTML tag, and customizing the HTML page, aiming to provide a consistent user interface and improve the overall user experience.', "Verified if the user exists and checked if the password is correct by implementing a long conditional statement with specific Python code. The chapter explains the verification process of the user's existence and the password correctness by implementing a long conditional statement with specific Python code, ensuring the security and accuracy of user login information.", "Installed the library 'flask_login', imported 'login_manager', and initiated the 'login_manager' instance. The chapter details the installation of the 'flask_login' library, the import of 'login_manager', and the initiation of the 'login_manager' instance, aiming to manage the login system efficiently within the Flask web application."]}], 'duration': 3063.024, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo12462438.jpg', 'highlights': ['The chapter details the process of updating the user registration form, including fixing validation errors, implementing hashed passwords for security, and installing Flask Bcrypt library to achieve this. This encapsulates the main focus of the chapter, highlighting the key points and quantitative data.', "The process involves creating a password property, setting up the password, using Bcrypt to generate password hash, and updating the route.py to handle hash passwords, ultimately resulting in successful implementation and verification of hash passwords for a new user, with the example of creating a new user 'JSC three' with a hashed password.", 'The chapter explains the process of creating a user login page, including designing a route, template, and form class, and ensuring proper functionality.', 'The chapter discusses the process of implementing the HTML logic in the registration form, creating a form HTML tag, and customizing the HTML page, aiming to provide a consistent user interface and improve the overall user experience.', "Installed the library 'flask_login', imported 'login_manager', and initiated the 'login_manager' instance. The chapter details the installation of the 'flask_login' library, the import of 'login_manager', and the initiation of the 'login_manager' instance, aiming to manage the login system efficiently within the Flask web application."]}, {'end': 16377.755, 'segs': [{'end': 15550.091, 'src': 'embed', 'start': 15525.462, 'weight': 2, 'content': [{'end': 15533.691, 'text': 'Wow, another wrong thing that I have done here is I did not provide the key that I want to filter out from.', 'start': 15525.462, 'duration': 8.229}, {'end': 15538.834, 'text': 'So excuse me really for mismatching the filter underscore by with the get function.', 'start': 15534.151, 'duration': 4.683}, {'end': 15544.957, 'text': "Basically, I'm doing this because it is working in another way in Django, the other framework of Python.", 'start': 15539.254, 'duration': 5.703}, {'end': 15550.091, 'text': 'So this should really be enough to go ahead and log in our users.', 'start': 15545.378, 'duration': 4.713}], 'summary': 'The key was not provided for filtering, and the get function was mismatched with the filter underscore.', 'duration': 24.629, 'max_score': 15525.462, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo15525462.jpg'}, {'end': 15969.226, 'src': 'embed', 'start': 15911.658, 'weight': 0, 'content': [{'end': 15924.467, 'text': 'from the very beginning of this tutorial I said that there are a lot of styling frameworks that does some job to really make our lives easier to import from some already designed styling.', 'start': 15911.658, 'duration': 12.809}, {'end': 15927.27, 'text': 'Now, we also have one of those too.', 'start': 15925.008, 'duration': 2.262}, {'end': 15929.371, 'text': 'use different icons.', 'start': 15928.21, 'duration': 1.161}, {'end': 15935.917, 'text': 'Now it could be a lot nicer if we will display an icon of a coins or something like that for our users.', 'start': 15929.852, 'duration': 6.065}, {'end': 15940.02, 'text': 'So the user can really understand that this is his budget.', 'start': 15936.357, 'duration': 3.663}, {'end': 15945.79, 'text': 'So we can do this by calling the I tag like this.', 'start': 15940.16, 'duration': 5.63}, {'end': 15952.314, 'text': 'And we can say class equals to fa s fa dash coins.', 'start': 15946.21, 'duration': 6.104}, {'end': 15961.861, 'text': 'And now we can say between those something like current underscore user dot budget, because, if you remember,', 'start': 15952.535, 'duration': 9.326}, {'end': 15966.184, 'text': 'this is the attribute that returns back the budget of our users.', 'start': 15961.861, 'duration': 4.323}, {'end': 15969.226, 'text': "Now I'd like to give this a little bit more styling.", 'start': 15966.744, 'duration': 2.482}], 'summary': "Using the fa s fa-dash-coins icon to display the user's budget for better understanding.", 'duration': 57.568, 'max_score': 15911.658, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo15911658.jpg'}, {'end': 16027.212, 'src': 'embed', 'start': 15998.163, 'weight': 1, 'content': [{'end': 16005.431, 'text': 'and colon, and we can say bold, and this should be enough to really display some nice information to our users about their budget.', 'start': 15998.163, 'duration': 7.268}, {'end': 16015.483, 'text': 'so we can go now to here and we can refresh and you can see that we have the icon of coins and we also have the number right here.', 'start': 16005.431, 'duration': 10.052}, {'end': 16018.645, 'text': 'Now I see that the aligning could be better in here.', 'start': 16015.743, 'duration': 2.902}, {'end': 16020.747, 'text': "So let's see what I have done wrong.", 'start': 16018.826, 'duration': 1.921}, {'end': 16027.212, 'text': 'And I think this is the fact that I put the text between the eye tags.', 'start': 16021.468, 'duration': 5.744}], 'summary': 'Improving budget display with coins icon and number for better user information.', 'duration': 29.049, 'max_score': 15998.163, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo15998163.jpg'}, {'end': 16357.027, 'src': 'embed', 'start': 16322.909, 'weight': 3, 'content': [{'end': 16330.95, 'text': 'And now we could call the exact same statement and print a now you can see that this works as well.', 'start': 16322.909, 'duration': 8.041}, {'end': 16346.262, 'text': 'So this is why I can grab this code from here and copy that out and paste this in right here as a return function like that.', 'start': 16331.37, 'duration': 14.892}, {'end': 16351.265, 'text': 'Okay, so after it, we shall change the self dot budget with P.', 'start': 16346.422, 'duration': 4.843}, {'end': 16353.105, 'text': 'So this should be something like that.', 'start': 16351.265, 'duration': 1.84}, {'end': 16357.027, 'text': 'And now we can add a dollar sign right here.', 'start': 16353.585, 'duration': 3.442}], 'summary': 'Demonstrating code functionality with self dot budget and dollar sign.', 'duration': 34.118, 'max_score': 16322.909, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo16322909.jpg'}], 'start': 15525.462, 'title': 'Customizing navigation bar and user authentication, styling budget display, and displaying comma', 'summary': 'Covers customizing the navigation bar based on user authentication, styling the budget display with icons, and displaying a comma in the fourth position from the right in a number string in python, demonstrating step-by-step modifications and examples.', 'chapters': [{'end': 15884.803, 'start': 15525.462, 'title': 'Customizing navigation bar and user authentication', 'summary': 'Covers customizing the navigation bar based on user authentication status, implementing conditional jinja syntax in html, and configuring the functionality of login and logout for users, demonstrating step-by-step modifications with live testing.', 'duration': 359.341, 'highlights': ['Implementing conditional Jinja syntax in HTML to customize navigation bar based on user authentication status The transcript details the process of using Jinja syntax in HTML to differentiate the options displayed to users based on their authentication status, emphasizing the implementation of conditional statements to modify the navigation bar.', 'Demonstrating step-by-step modifications and live testing for user authentication functionality The speaker provides a detailed demonstration of step-by-step modifications and live testing for user authentication functionality, emphasizing the practical application of the discussed concepts.', "Explaining the usage of Flask Login's built-in functions for accessing the current user's authentication status The transcript explains the usage of Flask Login's built-in functions to access the current user's authentication status, highlighting the practical significance of utilizing these functions in customizing user interactions."]}, {'end': 16154.816, 'start': 15884.803, 'title': 'Styling budget display with icons', 'summary': 'Demonstrates how to style the budget display for users, including adding an icon and implementing a function to add commas to the budget if it exceeds four digits.', 'duration': 270.013, 'highlights': ["Implementing an icon display for the user's budget using the 'I' tag and adding styling to the anchor tag with a green color and bold text. The tutorial showcases the addition of an icon for the user's budget using the 'I' tag and applying styling to the anchor tag with a green color and bold text for enhanced visibility.", 'Discussing the need to add a comma for budgets exceeding 1000 and outlining the implementation of a function in modules.py to format the budget with commas. The tutorial discusses the need to add a comma for budgets exceeding 1000 and outlines the implementation of a function in modules.py to format the budget with commas, enhancing the readability of larger budget amounts.']}, {'end': 16377.755, 'start': 16155.416, 'title': 'Displaying comma in the fourth position', 'summary': 'Demonstrates how to display a comma only in the fourth position from the right in a number string in python, using indexing and string manipulation, with examples of displaying commas in numbers such as 1000 and 100,000.', 'duration': 222.339, 'highlights': ['The chapter explains how to use indexing and string manipulation in Python to display a comma only in the fourth position from the right in a number string, exemplified with the numbers 1000 and 100,000.', 'Demonstrates the process of indexing the character at the minus three position from the right in a number string, with examples of displaying the zero and grabbing all digits till the minus three position.', "Illustrates the use of Python's formatted string and indexing to achieve the desired behavior of displaying a comma after reaching the third digit from the right in a number string."]}], 'duration': 852.293, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo15525462.jpg', 'highlights': ['Demonstrating step-by-step modifications and live testing for user authentication functionality', 'Implementing conditional Jinja syntax in HTML to customize navigation bar based on user authentication status', "Explaining the usage of Flask Login's built-in functions for accessing the current user's authentication status", "Implementing an icon display for the user's budget using the 'I' tag and adding styling to the anchor tag with a green color and bold text", 'Discussing the need to add a comma for budgets exceeding 1000 and outlining the implementation of a function in modules.py to format the budget with commas', 'The chapter explains how to use indexing and string manipulation in Python to display a comma only in the fourth position from the right in a number string']}, {'end': 17455.932, 'segs': [{'end': 16506.099, 'src': 'embed', 'start': 16448.524, 'weight': 0, 'content': [{'end': 16456.887, 'text': 'And then this route will know to log out the logged in user, and then we will finish it with redirecting our users back to homepage.', 'start': 16448.524, 'duration': 8.363}, {'end': 16459.33, 'text': 'So we will open our PyCharm here.', 'start': 16457.367, 'duration': 1.963}, {'end': 16463.534, 'text': "And actually, I see that I'm inside my base dot HTML.", 'start': 16459.771, 'duration': 3.763}, {'end': 16467.658, 'text': "And it might be a great idea to show you what I'm going to configure in the future.", 'start': 16464.015, 'duration': 3.643}, {'end': 16472.863, 'text': 'So if you remember, then we have this log out.', 'start': 16468.139, 'duration': 4.724}, {'end': 16474.325, 'text': 'anchor tag.', 'start': 16473.704, 'duration': 0.621}, {'end': 16480.972, 'text': 'And then inside here, we are going to send our users to that URL underscore four.', 'start': 16474.705, 'duration': 6.267}, {'end': 16485.216, 'text': "So actually, if I'm on the base dot HTML, then I'm going to do that.", 'start': 16481.472, 'duration': 3.744}, {'end': 16494.747, 'text': 'So I will zoom in and I will basically copy this from here and paste this in to here.', 'start': 16485.757, 'duration': 8.99}, {'end': 16498.391, 'text': 'And I will change this to log out.', 'start': 16495.167, 'duration': 3.224}, {'end': 16506.099, 'text': "Now you are probably asking yourself why you are using this URL for logout page, although you didn't create the route.", 'start': 16498.891, 'duration': 7.208}], 'summary': 'Configuring logout functionality and redirecting users to homepage.', 'duration': 57.575, 'max_score': 16448.524, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo16448524.jpg'}, {'end': 16850.203, 'src': 'embed', 'start': 16819.685, 'weight': 4, 'content': [{'end': 16825.228, 'text': 'So if I save this, and go back to our home.html and refresh that out.', 'start': 16819.685, 'duration': 5.543}, {'end': 16832.032, 'text': 'Then you can see that we have a nice home kind of a banner that really shows that this is our homepage.', 'start': 16825.569, 'duration': 6.463}, {'end': 16838.656, 'text': 'Now, if I click on get started, you can already see that it leads us to the market page,', 'start': 16832.513, 'duration': 6.143}, {'end': 16843.699, 'text': 'thanks to that URL for market page that is inside that anchor tag.', 'start': 16838.656, 'duration': 5.043}, {'end': 16850.203, 'text': 'Now, here, we actually have some problem that you already maybe paid attention or not.', 'start': 16844.259, 'duration': 5.944}], 'summary': "Updating home.html created a visible banner; 'get started' link directs to market page.", 'duration': 30.518, 'max_score': 16819.685, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo16819685.jpg'}, {'end': 17455.932, 'src': 'embed', 'start': 17364.315, 'weight': 2, 'content': [{'end': 17373.62, 'text': 'now. if nothing goes wrong with those two lines, then it means that the user has been created successfully, so we can log in that user now.', 'start': 17364.315, 'duration': 9.305}, {'end': 17378.902, 'text': 'once we do this, then we can type in a message like the following.', 'start': 17373.62, 'duration': 5.282}, {'end': 17400.401, 'text': "so it will be let's write in a formatted string here and we can say account created successfully and we can say you are now logged in as and we can say user to create that username like that.", 'start': 17378.902, 'duration': 21.499}, {'end': 17405.945, 'text': "Okay, so let's test this out with another user that we probably want to create now.", 'start': 17400.921, 'duration': 5.024}, {'end': 17418.033, 'text': 'Now I forgot to specify the category, so excuse me for that, and it is a great idea to actually go ahead and say category equals to success,', 'start': 17406.405, 'duration': 11.628}, {'end': 17420.684, 'text': 'exactly like that.', 'start': 17419.022, 'duration': 1.662}, {'end': 17426.01, 'text': 'okay, so now we can go here and we can try to register again.', 'start': 17420.684, 'duration': 5.326}, {'end': 17433.199, 'text': 'so we will create the jsc7 that time and we will try to create the.', 'start': 17426.01, 'duration': 7.189}, {'end': 17436.621, 'text': 'we will try to fill in valid information.', 'start': 17434.54, 'duration': 2.081}, {'end': 17438.402, 'text': 'So we can click on create account.', 'start': 17436.681, 'duration': 1.721}, {'end': 17441.844, 'text': 'And now you can see that we are already in the slash market.', 'start': 17438.822, 'duration': 3.022}, {'end': 17445.466, 'text': 'And it says us that we are logged in as GSC seven.', 'start': 17442.284, 'duration': 3.182}, {'end': 17447.507, 'text': 'So it is a lot better now,', 'start': 17445.806, 'duration': 1.701}, {'end': 17455.932, 'text': 'because the new clients that are going to register to that website are going to have a lot better experience with this approach.', 'start': 17447.507, 'duration': 8.425}], 'summary': 'Successfully created user and logged in, improving user experience.', 'duration': 91.617, 'max_score': 17364.315, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo17364315.jpg'}], 'start': 16377.995, 'title': 'Website dynamic updates and user experience enhancements', 'summary': "Covers the implementation of dynamic property 'prettier_budget' in base dot html, configuring logout functionality, customizing homepage, and automated login page redirection, resulting in a website with dynamic formatting, improved user experience, and login page redirection feature.", 'chapters': [{'end': 16426.746, 'start': 16377.995, 'title': 'Dynamic property implementation', 'summary': "Discusses the implementation of a dynamic property 'prettier_budget' in the base dot html, resulting in a website that displays a budget with dynamic formatting, allowing for future updates and purchases.", 'duration': 48.751, 'highlights': ["The dynamic property 'prettier_budget' was implemented in the base dot HTML, resulting in a website that displays a budget with dynamic formatting, allowing for future updates and purchases.", 'The comma in the budget display disappears when items are purchased, showcasing the dynamic nature of the implemented property.', "Running the website using 'Python run dot py' command in the terminal ensures the website is up and running."]}, {'end': 16982.717, 'start': 16429.676, 'title': 'Configuring logout and customizing homepage', 'summary': "Covers configuring the logout functionality by adding a route to log out the user and redirecting to the homepage, as well as customizing the homepage by adding a logo and 'get started' button, with a link to the market page. the chapter also introduces a function to prevent unlogged users from accessing the market page.", 'duration': 553.041, 'highlights': ["The chapter covers configuring the logout functionality by adding a route to log out the user and redirecting to the homepage, as well as customizing the homepage by adding a logo and 'get started' button, with a link to the market page.", 'Introducing a function to prevent unlogged users from accessing the market page.', "Demonstrating the use of Flask's built-in 'login_required' function as a decorator to prevent unlogged users from accessing the market page."]}, {'end': 17455.932, 'start': 16982.877, 'title': 'Automated login page redirection', 'summary': 'Demonstrates the implementation of a login page redirection feature, which automatically directs users to the login page if they are not authorized, and also includes the creation and login of new user accounts, resulting in a better user experience.', 'duration': 473.055, 'highlights': ['The chapter demonstrates the implementation of a login page redirection feature, which automatically directs users to the login page if they are not authorized. ', 'The creation and login of new user accounts are shown, resulting in a better user experience for new clients registering on the website. ', 'The addition of a flashed message and login of the user upon account creation is showcased, providing a smoother user experience for new registrants. ']}], 'duration': 1077.937, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo16377995.jpg', 'highlights': ["The dynamic property 'prettier_budget' was implemented in the base dot HTML, resulting in a website that displays a budget with dynamic formatting, allowing for future updates and purchases.", 'The comma in the budget display disappears when items are purchased, showcasing the dynamic nature of the implemented property.', "The chapter covers configuring the logout functionality by adding a route to log out the user and redirecting to the homepage, as well as customizing the homepage by adding a logo and 'get started' button, with a link to the market page.", 'The chapter demonstrates the implementation of a login page redirection feature, which automatically directs users to the login page if they are not authorized.', 'Introducing a function to prevent unlogged users from accessing the market page.', "Running the website using 'Python run dot py' command in the terminal ensures the website is up and running."]}, {'end': 20379.313, 'segs': [{'end': 17562.391, 'src': 'embed', 'start': 17535.345, 'weight': 7, 'content': [{'end': 17540.469, 'text': 'So this section includes a div tag and it says that class equals to row.', 'start': 17535.345, 'duration': 5.124}, {'end': 17543.131, 'text': 'Now the gridding system could be implemented.', 'start': 17540.89, 'duration': 2.241}, {'end': 17549.716, 'text': 'the second, that you create a div tag with a class of row, because it is just as it sounds,', 'start': 17543.131, 'duration': 6.585}, {'end': 17555.082, 'text': 'because it is going to create a row that is going to be expanded to the entire page.', 'start': 17549.716, 'duration': 5.366}, {'end': 17558.306, 'text': 'So we could grab the row that is created.', 'start': 17555.483, 'duration': 2.823}, {'end': 17562.391, 'text': "And we could customize the way that we'd like to divide it.", 'start': 17558.687, 'duration': 3.704}], 'summary': 'Using div tags with class=row for grid system implementation.', 'duration': 27.046, 'max_score': 17535.345, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo17535345.jpg'}, {'end': 18023.244, 'src': 'embed', 'start': 17997.742, 'weight': 0, 'content': [{'end': 18006.386, 'text': 'And it totally focuses us to really look at the new output that appears to us because it grays the entire background of the web page.', 'start': 17997.742, 'duration': 8.644}, {'end': 18008.247, 'text': "So let's actually see a demo of that.", 'start': 18006.506, 'duration': 1.741}, {'end': 18015.935, 'text': "So we have this HTML code in here, which is basically responsible to display the model that I'm talking about.", 'start': 18008.647, 'duration': 7.288}, {'end': 18023.244, 'text': 'And basically, this model could be configured as a behind the scenes functionality of what happens when we click on a button.', 'start': 18016.056, 'duration': 7.188}], 'summary': 'A demonstration of a model configured to trigger an action through a button click.', 'duration': 25.502, 'max_score': 17997.742, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo17997742.jpg'}, {'end': 18144.724, 'src': 'embed', 'start': 18116.527, 'weight': 4, 'content': [{'end': 18122.371, 'text': 'So to avoid this, we could locate our model in a separated HTML template.', 'start': 18116.527, 'duration': 5.844}, {'end': 18129.256, 'text': 'And then this market dot HTML could import this model that we want to create.', 'start': 18122.711, 'duration': 6.545}, {'end': 18136.58, 'text': 'Now the way that is going to be designed, it is by creating one more directory that we will name it includes.', 'start': 18129.716, 'duration': 6.864}, {'end': 18144.724, 'text': "And within that includes directory that we're going to create, we are going to create some HTML files that are going to be like helper files.", 'start': 18136.92, 'duration': 7.804}], 'summary': "To avoid issues, the model can be placed in a separate html template, imported into market.html, and organized in an 'includes' directory.", 'duration': 28.197, 'max_score': 18116.527, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo18116527.jpg'}, {'end': 18404.249, 'src': 'embed', 'start': 18376.856, 'weight': 10, 'content': [{'end': 18388.44, 'text': "the value that we'd like to give here is the exact same name of the identifier of the model that we'd like to display.", 'start': 18376.856, 'duration': 11.584}, {'end': 18395.502, 'text': 'So this is why I said previously that this identifier string is going to be quite important for us in the future.', 'start': 18388.84, 'duration': 6.662}, {'end': 18404.249, 'text': 'So I will allow myself to copy this entire string and paste this in right inside our data target.', 'start': 18395.962, 'duration': 8.287}], 'summary': 'The identifier string is crucial for displaying the model and needs to be copied into the data target.', 'duration': 27.393, 'max_score': 18376.856, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo18376856.jpg'}, {'end': 18646.705, 'src': 'embed', 'start': 18617.929, 'weight': 5, 'content': [{'end': 18628.776, 'text': 'So the way that we can change this is changing the location of where we import that model and actually import it inside our for loop.', 'start': 18617.929, 'duration': 10.847}, {'end': 18632.419, 'text': 'And that way we can customize it to be unique per item.', 'start': 18629.056, 'duration': 3.363}, {'end': 18634.3, 'text': "So let's go ahead and do that.", 'start': 18632.879, 'duration': 1.421}, {'end': 18646.705, 'text': 'Now I will make this market.html bigger for a second and I will grab the code snippet which is include, includes items modals.html,', 'start': 18634.84, 'duration': 11.865}], 'summary': 'Changing the model import location to customize it for each item.', 'duration': 28.776, 'max_score': 18617.929, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo18617929.jpg'}, {'end': 18797.131, 'src': 'embed', 'start': 18770.152, 'weight': 8, 'content': [{'end': 18781.58, 'text': 'our data target is now pointing to a wrong location because it should be the same as the identifier string of the model itself.', 'start': 18770.152, 'duration': 11.428}, {'end': 18783.942, 'text': 'So now I will copy this out.', 'start': 18782.001, 'duration': 1.941}, {'end': 18787.044, 'text': 'And I will paste this in like that.', 'start': 18784.362, 'duration': 2.682}, {'end': 18795.09, 'text': 'And now that I have done this, then basically, we were able to achieve to create models that are unique per item.', 'start': 18787.605, 'duration': 7.485}, {'end': 18797.131, 'text': "So let's test the result of that.", 'start': 18795.47, 'duration': 1.661}], 'summary': 'Data target fixed, models now unique per item.', 'duration': 26.979, 'max_score': 18770.152, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo18770152.jpg'}, {'end': 19210.386, 'src': 'embed', 'start': 19183.143, 'weight': 3, 'content': [{'end': 19191.732, 'text': 'then maybe under the question mark I mean the question itself that asks us if we want to buy this item for that amount of price.', 'start': 19183.143, 'duration': 8.589}, {'end': 19194.274, 'text': 'we probably want to create a form.', 'start': 19191.732, 'duration': 2.542}, {'end': 19198.478, 'text': 'So I will just start with creating the tags of it.', 'start': 19194.735, 'duration': 3.743}, {'end': 19208.525, 'text': 'So it will be form and then we will say method equals to post, like we did with the login and with the register system.', 'start': 19199.159, 'duration': 9.366}, {'end': 19210.386, 'text': "Now I'm going to stop here.", 'start': 19209.005, 'duration': 1.381}], 'summary': 'Creating a form with method equals to post for item purchase.', 'duration': 27.243, 'max_score': 19183.143, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo19183143.jpg'}, {'end': 19635.175, 'src': 'embed', 'start': 19606.294, 'weight': 11, 'content': [{'end': 19610.258, 'text': 'And you can see that we initialize this purchase underscore form.', 'start': 19606.294, 'duration': 3.964}, {'end': 19619.404, 'text': 'Now, regularly, we would like to go with the approach that we have done for the login and the register forms as well.', 'start': 19610.818, 'duration': 8.586}, {'end': 19629.371, 'text': 'So we probably want to run such a code, which is going to be like purchase form that validate on submit.', 'start': 19619.845, 'duration': 9.526}, {'end': 19632.674, 'text': 'Okay, so it is going to be exactly the same thing.', 'start': 19629.731, 'duration': 2.943}, {'end': 19635.175, 'text': "But let's not forget the if statement in here.", 'start': 19632.774, 'duration': 2.401}], 'summary': 'Initializing purchase form, running code for validation on submit.', 'duration': 28.881, 'max_score': 19606.294, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo19606294.jpg'}, {'end': 19788.9, 'src': 'embed', 'start': 19754.877, 'weight': 6, 'content': [{'end': 19766.929, 'text': 'Now, if we search for the key of submit, then you can see that we actually see the submit field as an object itself.', 'start': 19754.877, 'duration': 12.052}, {'end': 19772.451, 'text': 'Now this means that we have an available key within this instance.', 'start': 19767.449, 'duration': 5.002}, {'end': 19775.652, 'text': 'So we could access it with a square brackets.', 'start': 19772.791, 'duration': 2.861}, {'end': 19781.413, 'text': 'So we could go to here, and we could delete this from here like that.', 'start': 19776.052, 'duration': 5.361}, {'end': 19786.097, 'text': 'And we could say, submit like a dictionary.', 'start': 19781.774, 'duration': 4.323}, {'end': 19788.9, 'text': 'Okay, so it is fine to run such a code.', 'start': 19786.277, 'duration': 2.623}], 'summary': "The transcript discusses accessing and manipulating a 'submit' key as an object, demonstrating code functionality.", 'duration': 34.023, 'max_score': 19754.877, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo19754877.jpg'}, {'end': 20091.363, 'src': 'embed', 'start': 20062.115, 'weight': 2, 'content': [{'end': 20064.176, 'text': "And let's try to purchase the iPhone 10.", 'start': 20062.115, 'duration': 2.061}, {'end': 20066.557, 'text': "So I'm going to click on purchase item.", 'start': 20064.176, 'duration': 2.381}, {'end': 20071.884, 'text': 'And once I have done that, then you can see that we see the output of iPhone 10.', 'start': 20067.017, 'duration': 4.867}, {'end': 20078.994, 'text': 'So that means that we have now fully control and we are aware which item our user tried to purchase.', 'start': 20071.884, 'duration': 7.11}, {'end': 20082.359, 'text': 'So now we can continue on taking more actions from here.', 'start': 20079.395, 'duration': 2.964}, {'end': 20091.363, 'text': 'Alright, so if you remember, I said that we are going to fix the always being shown output about the form resubmission thing.', 'start': 20082.619, 'duration': 8.744}], 'summary': 'Demonstrating control over user purchase, fixing form resubmission issue', 'duration': 29.248, 'max_score': 20062.115, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo20062115.jpg'}, {'end': 20134.819, 'src': 'embed', 'start': 20104.75, 'weight': 1, 'content': [{'end': 20110.792, 'text': 'So to avoid this, we actually have to get rid of the conditional form dot validate on submit.', 'start': 20104.75, 'duration': 6.042}, {'end': 20121.214, 'text': 'Because the reason this pop up shows here, it is because every time that we go inside this route, then it tries to submit some form that executes.', 'start': 20111.232, 'duration': 9.982}, {'end': 20128.056, 'text': "And the reason is because we don't differentiate between get request to post request.", 'start': 20121.594, 'duration': 6.462}, {'end': 20134.819, 'text': 'But now that we have fully control of the request object, we can differentiate between those request types.', 'start': 20128.536, 'duration': 6.283}], 'summary': 'Removing form validation on submit to differentiate between get and post requests resolves the pop-up issue.', 'duration': 30.069, 'max_score': 20104.75, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo20104750.jpg'}, {'end': 20284.38, 'src': 'embed', 'start': 20250.993, 'weight': 9, 'content': [{'end': 20256.319, 'text': "So I'm going to say if P item object and then enter this condition.", 'start': 20250.993, 'duration': 5.326}, {'end': 20264.247, 'text': "And now once we have this P item object, we'd like to assign an ownership to the user that is currently logged in.", 'start': 20256.559, 'duration': 7.688}, {'end': 20273.577, 'text': 'Now, we did not see this before, but we have a built in object that is always going to refer to the current logged in user object.', 'start': 20264.808, 'duration': 8.769}, {'end': 20284.38, 'text': 'So the way that we can import this is going to be as easy as going up top here and import from flask login the current user built in object.', 'start': 20274.137, 'duration': 10.243}], 'summary': 'Assign ownership to the current user using the p item object and flask login.', 'duration': 33.387, 'max_score': 20250.993, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo20250993.jpg'}], 'start': 17458.996, 'title': 'Website enhancement and customization', 'summary': 'Discusses enhancing market page display, implementing logic and styling with bootstrap, customizing website models, updating modal and form fields, and creating a purchase form with successful ownership assignment.', 'chapters': [{'end': 17808.451, 'start': 17458.996, 'title': 'Market page display enhancement', 'summary': 'Discusses modifying the market page display by dividing it into two sections to show available and purchased items, using the bootstrap grid system and custom styling. the page will be more focused and cleaner with a left pane for available items and a right pane for purchased items.', 'duration': 349.455, 'highlights': ['The market page display will be modified by dividing it into two main sections: available items and purchased items. This modification aims to create a more focused page about the entire website, with a left pane for available items and a right pane for purchased items.', 'The bootstrap grid system will be used to implement the division of the page. The bootstrap grid system will allow for the creation of a row that expands to the entire page and the alignment of HTML pages using column tags.', "Custom styling, including margin adjustments, will be applied to the divided sections to enhance the page's visual appeal. Custom styling, such as adding a margin of 20 pixels for top and left, will be used to create a cleaner and more visually appealing division of the page."]}, {'end': 18535.074, 'start': 17808.672, 'title': 'Implementing logic and styling with bootstrap', 'summary': 'Covers implementing functionality for buttons, adding titles to page sections, and integrating modal pop-ups. it includes customizing modal styles and importing html templates to organize code.', 'duration': 726.402, 'highlights': ['Implementing functionality for buttons Describes the process of implementing functionality for buttons, such as changing the button text and adding functionality to click actions.', 'Adding titles to page sections Explains the importance of adding descriptive titles to page sections for user understanding and provides an example of adding a title above a table tag.', 'Integrating modal pop-ups Discusses the use of modal pop-ups to display additional information to users and the process of connecting buttons to trigger modal pop-ups.', 'Customizing modal styles Demonstrates the customization of modal styles, including changing the background color, to enhance the visual appearance of the modal pop-up.', 'Importing HTML templates to organize code Details the process of importing HTML templates from separate files to ensure organized code structure and maintainability.']}, {'end': 18892.363, 'start': 18535.234, 'title': 'Website models customization', 'summary': 'Focuses on customizing website models to display unique paragraphs for each item, achieved by importing the model inside the for loop and using unique identifiers and item-specific fields, resulting in models that are unique per item.', 'duration': 357.129, 'highlights': ['Importing the model inside the for loop allows customization for each item, resulting in unique models per item.', 'Using unique identifiers and item-specific fields like item ID and item description helps in creating unique models per item.', 'The process of customizing the purchase item model is similar to customizing the more info model, illustrating a consistent approach to model customization.']}, {'end': 19470.896, 'start': 18892.403, 'title': 'Updating modal and form fields', 'summary': 'Describes the process of updating modal and form fields, including changing identifier strings, modifying model body text, creating new form fields, and passing form instances as context to templates.', 'duration': 578.493, 'highlights': ['The chapter describes the process of updating modal and form fields The transcript discusses the process of updating modal and form fields to improve the user experience on the website.', 'Changing identifier strings and model body text The speaker explains the importance of changing identifier strings to avoid duplicate ID references and modifying the model body text to enhance the user interface.', 'Creating new form fields and passing form instances as context to templates The process of creating new form fields for purchasing items and passing form instances as context to templates is detailed, providing insights into the backend implementation.']}, {'end': 20379.313, 'start': 19471.337, 'title': 'Creating a purchase form and handling form submission', 'summary': 'Details the process of creating and handling a purchase form, including the initialization of the form, modifying the form fields, testing the form submission, and differentiating between request types. it also covers filtering and assigning ownership to the item object based on the form input, ultimately ensuring successful form submission and ownership assignment.', 'duration': 907.976, 'highlights': ['The chapter details the process of creating and handling a purchase form The transcript focuses on the creation and handling of a purchase form, demonstrating the step-by-step process and the underlying code logic.', 'Filtering and assigning ownership to the item object based on the form input The chapter covers the process of filtering the item object based on form input and assigning ownership to the filtered item, ensuring that the ownership is successfully assigned.', 'Differentiating between request types and modifying form submission handling It explains the differentiation between request types, specifically between get and post requests, and modifying form submission handling to avoid displaying unnecessary output.']}], 'duration': 2920.317, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo17458996.jpg', 'highlights': ['The market page display will be modified by dividing it into two main sections: available items and purchased items.', 'The bootstrap grid system will be used to implement the division of the page.', "Custom styling, including margin adjustments, will be applied to the divided sections to enhance the page's visual appeal.", 'The process of importing HTML templates from separate files to ensure organized code structure and maintainability.', 'Importing the model inside the for loop allows customization for each item, resulting in unique models per item.', 'The process of customizing the purchase item model is similar to customizing the more info model, illustrating a consistent approach to model customization.', 'The chapter describes the process of updating modal and form fields to improve the user experience on the website.', 'Changing identifier strings to avoid duplicate ID references and modifying the model body text to enhance the user interface.', 'Creating new form fields for purchasing items and passing form instances as context to templates, providing insights into the backend implementation.', 'The chapter details the process of creating and handling a purchase form, demonstrating the step-by-step process and the underlying code logic.', 'Filtering and assigning ownership to the item object based on the form input, ensuring that the ownership is successfully assigned.', 'Differentiating between request types, specifically between get and post requests, and modifying form submission handling to avoid displaying unnecessary output.']}, {'end': 21402.72, 'segs': [{'end': 20635.93, 'src': 'embed', 'start': 20608.516, 'weight': 0, 'content': [{'end': 20614.84, 'text': 'and now we could refer to the variable of the item name by changing this to formatted string.', 'start': 20608.516, 'duration': 6.324}, {'end': 20618.323, 'text': 'And we could say P item object dot name.', 'start': 20615.321, 'duration': 3.002}, {'end': 20626.568, 'text': 'you purchased item object dot name for and we could specify the price of the item itself.', 'start': 20619.246, 'duration': 7.322}, {'end': 20632.609, 'text': 'So we could say P item object again, and we could refer to that price attribute.', 'start': 20626.668, 'duration': 5.941}, {'end': 20635.93, 'text': 'So this should be great to really flash the message itself.', 'start': 20633.029, 'duration': 2.901}], 'summary': 'Referring to the item name and price for a purchase using formatted strings and object attributes.', 'duration': 27.414, 'max_score': 20608.516, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo20608516.jpg'}, {'end': 20739.788, 'src': 'embed', 'start': 20713.218, 'weight': 2, 'content': [{'end': 20723.501, 'text': 'So this is why we should write some logic to prevent from our users to have the ability to purchase an item that their budget is not enough for it.', 'start': 20713.218, 'duration': 10.283}, {'end': 20727.183, 'text': 'So this is why we should write some more Python code.', 'start': 20723.942, 'duration': 3.241}, {'end': 20728.703, 'text': "So I'm going to go here.", 'start': 20727.563, 'duration': 1.14}, {'end': 20739.788, 'text': 'And now we could basically imagine a code that is going to say something like if current user can purchase.', 'start': 20729.263, 'duration': 10.525}], 'summary': 'Implement logic to prevent users from purchasing items beyond their budget.', 'duration': 26.57, 'max_score': 20713.218, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo20713218.jpg'}, {'end': 21412.385, 'src': 'embed', 'start': 21382.128, 'weight': 1, 'content': [{'end': 21387.331, 'text': 'So this is why I can allow myself to filter this out by current user.id.', 'start': 21382.128, 'duration': 5.203}, {'end': 21391.374, 'text': 'And this should be enough to bring all the items that the current user owns them.', 'start': 21387.711, 'duration': 3.663}, {'end': 21402.72, 'text': 'So now I will pass this as a context by saying owned underscore items equals to owned items like that.', 'start': 21391.814, 'duration': 10.906}, {'end': 21412.385, 'text': 'Okay, so this really should be enough to go now to our market dot HTML and start working on the implementation of how we want to display this.', 'start': 21403.481, 'duration': 8.904}], 'summary': 'Filter and display owned items for current user on market html.', 'duration': 30.257, 'max_score': 21382.128, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo21382128.jpg'}], 'start': 20379.654, 'title': 'Implementing user budget reduction and item purchase logic', 'summary': "Discusses reducing a user's budget, executing a save operation, implementing purchase filters, preventing overbudget purchases with python code, and assigning items to users with model refactoring.", 'chapters': [{'end': 20692.063, 'start': 20379.654, 'title': 'User budget reduction and item purchase', 'summary': "Discusses the process of reducing a user's budget by subtracting the item's price, executing a save operation in the database, testing the purchase of an item, and implementing filters to display available items. it also covers displaying a success message after a purchase and preventing resubmission output.", 'duration': 312.409, 'highlights': ["The process of reducing a user's budget by subtracting the item's price involves executing the line 'current_user.budget -= item.price' and then performing a save operation towards the database using 'DB.session.commit()'. This process involves directly decreasing the user's budget by subtracting the item's price, followed by the execution of a save operation towards the database.", "The demonstration includes testing the purchase of an item, where it is expected to see the budget reduced to $200 after purchasing the iPhone 10. The testing of the purchase involves the expectation of the user's budget being reduced to $200 after purchasing the iPhone 10.", "Implementation of filters to display available items involves filtering items by owner equals to none, ensuring that only items without an owner are displayed in the available item section. The implementation of filters ensures that items without an owner are displayed in the available item section by filtering items with 'owner equals to none'.", "Displaying a success message after a purchase is achieved by using 'flash' to raise a message congratulating the user for purchasing the item and displaying the item's name and price. The success message after a purchase is displayed using 'flash' to congratulate the user and display the item's name and price in a formatted string.", "The prevention of resubmission output is accomplished by conditioning the execution of certain lines to only occur if the request type is 'get', thereby avoiding the display of the confirm resubmission output. To prevent the resubmission output, the execution of certain lines is conditioned to occur only if the request type is 'get', ensuring that the confirm resubmission output is not displayed."]}, {'end': 21013.958, 'start': 20692.063, 'title': 'Implementing logic for preventing overbudget purchases', 'summary': "Discusses the need to implement logic to prevent users from purchasing items if their budget is not enough, and demonstrates using python code to check the user's budget before allowing the purchase, resulting in a successful prevention of overbudget purchases.", 'duration': 321.895, 'highlights': ["Implemented logic to prevent users from purchasing items if their budget is not enough, using Python code to check the user's budget before allowing the purchase, resulting in a successful prevention of overbudget purchases.", "Added a function in the user model to verify if the user's budget is greater than or equal to the item object's price, returning a Boolean value that determines whether the user can purchase the item.", "Included conditional statements in the routes.py file to handle cases where the user's budget is not sufficient for the item, raising flash messages with appropriate categories and redirecting the user back to the market page after a post request completes."]}, {'end': 21402.72, 'start': 21014.279, 'title': 'Item ownership and model refactoring', 'summary': 'Covers the process of assigning an item to a user, refactoring code into a method inside the item model, testing the functionality with different users, and querying items owned by the current user for display in the market page.', 'duration': 388.441, 'highlights': ["Users can assign items to themselves using the 'by' method in the item model, simplifying the code and improving readability. The 'by' method in the item model allows users to assign items to themselves, improving code readability and user interaction.", 'The system is tested with a new user who has a default budget of $1000, showcasing the functionality of assigning and purchasing items. Testing the system with a new user having a default budget of $1000 demonstrates the functionality of assigning and purchasing items.', 'Querying owned items by the current user is implemented to facilitate the display of owned items in the market page, enhancing user experience. Implementing a query to fetch items owned by the current user enhances the user experience by displaying owned items in the market page.']}], 'duration': 1023.066, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo20379654.jpg', 'highlights': ["The prevention of resubmission output is accomplished by conditioning the execution of certain lines to only occur if the request type is 'get', ensuring that the confirm resubmission output is not displayed.", 'Implemented logic to prevent users from purchasing items if their budget is not enough, resulting in a successful prevention of overbudget purchases.', 'Querying owned items by the current user is implemented to facilitate the display of owned items in the market page, enhancing user experience.']}, {'end': 22862.774, 'segs': [{'end': 21857.005, 'src': 'embed', 'start': 21826.793, 'weight': 0, 'content': [{'end': 21831.254, 'text': 'And, like I said, because the logic implementation is going to be quite the same,', 'start': 21826.793, 'duration': 4.461}, {'end': 21837.136, 'text': 'I can allow myself to grab the exact same model from the purchasing item model.', 'start': 21831.254, 'duration': 5.882}, {'end': 21845.078, 'text': 'And later on, we could change some of the identifier strings or HTML text to make it dedicated for selling an item.', 'start': 21837.496, 'duration': 7.582}, {'end': 21857.005, 'text': 'Okay, so I will go to items underscore models and I will copy the entire code under the purchase confirm and I will paste this in here.', 'start': 21845.638, 'duration': 11.367}], 'summary': 'Implementing logic for selling items by reusing code from purchasing item model.', 'duration': 30.212, 'max_score': 21826.793, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo21826793.jpg'}, {'end': 21959.862, 'src': 'embed', 'start': 21927.212, 'weight': 1, 'content': [{'end': 21938.696, 'text': 'And in here, we could say by clicking sell, you will put this item back on market like that.', 'start': 21927.212, 'duration': 11.484}, {'end': 21943.697, 'text': 'Now you can already see the input inside this model as well.', 'start': 21939.296, 'duration': 4.401}, {'end': 21947.778, 'text': 'And you can see that it has an identifier that says purchase item.', 'start': 21944.177, 'duration': 3.601}, {'end': 21952.02, 'text': 'So it totally makes sense to change this to sold item.', 'start': 21948.178, 'duration': 3.842}, {'end': 21957.361, 'text': 'Okay, so we created this in past tense, so we will leave it as it is.', 'start': 21952.04, 'duration': 5.321}, {'end': 21959.862, 'text': 'And this will be sold item as well.', 'start': 21957.821, 'duration': 2.041}], 'summary': "Changing the identifier from 'purchase item' to 'sold item' and creating the model in past tense.", 'duration': 32.65, 'max_score': 21927.212, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo21927212.jpg'}, {'end': 22045.291, 'src': 'embed', 'start': 22015.693, 'weight': 2, 'content': [{'end': 22026.3, 'text': 'and we like to do this split vertically and in the left pane we will keep the owned items models and in the right pane we will open the,', 'start': 22015.693, 'duration': 10.607}, {'end': 22028.364, 'text': 'not the items model.', 'start': 22027.304, 'duration': 1.06}, {'end': 22030.665, 'text': 'excuse me, we will open market.html.', 'start': 22028.364, 'duration': 2.301}, {'end': 22033.266, 'text': 'Okay, so from here, we are good to go.', 'start': 22031.145, 'duration': 2.121}, {'end': 22036.887, 'text': "And let's scroll down a bit in here.", 'start': 22033.986, 'duration': 2.901}, {'end': 22045.291, 'text': "And you can see that we have under call for some more things that we'd like to change in here.", 'start': 22037.647, 'duration': 7.644}], 'summary': 'Split screen to compare owned items models against market.html and make necessary changes.', 'duration': 29.598, 'max_score': 22015.693, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo22015693.jpg'}, {'end': 22133.199, 'src': 'embed', 'start': 22105.394, 'weight': 3, 'content': [{'end': 22116.601, 'text': 'so to really make our lives easier in here we could basically search for item and we could pay attention that Every item is with owned item right now.', 'start': 22105.394, 'duration': 11.207}, {'end': 22118.843, 'text': 'So we are good to go from here.', 'start': 22116.701, 'duration': 2.142}, {'end': 22124.01, 'text': 'And now I can really copy this identifier string and copy that out.', 'start': 22119.444, 'duration': 4.566}, {'end': 22129.957, 'text': 'And now I will make the market.html bigger and we could paste this in.', 'start': 22124.51, 'duration': 5.447}, {'end': 22133.199, 'text': 'right in here like that.', 'start': 22130.698, 'duration': 2.501}], 'summary': 'Improving efficiency by searching for and organizing items, and copying identifier strings for use in market.html.', 'duration': 27.805, 'max_score': 22105.394, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo22105394.jpg'}], 'start': 21403.481, 'title': 'Market html implementation and bootstrap cards', 'summary': "Discusses implementing available and owned items on the market using html and bootstrap, and creating bootstrap cards in html, adapting existing code from a purchase model, and implementing a model trigger in market.html. it also details the process of implementing the selling logic in the routes.py file, leading to the website's completion.", 'chapters': [{'end': 21507.818, 'start': 21403.481, 'title': 'Market html implementation', 'summary': 'Discusses the implementation of displaying available and owned items on the market using html and bootstrap, including the use of div classes to organize and iterate through the items.', 'duration': 104.337, 'highlights': ['The implementation involves using div classes and iterations to display available and owned items on the market, with a specific focus on organizing the layout using Bootstrap grid system and ensuring proper display of items in rows and columns.', "The div class is set to 'call-md-6' to ensure that items are displayed in rows of two, as the maximum size for an HTML element within a row is 12, providing a clear explanation for the choice of column size.", "The reasoning behind setting the div class to 'call-md-6' is to ensure that when there are more than two items, they are forced to jump down a row, creating a visually appealing layout for the displayed items."]}, {'end': 21987.033, 'start': 21508.298, 'title': 'Creating bootstrap cards and modifying html', 'summary': 'Details the process of creating bootstrap cards in html, including the code implementation and visual results, as well as modifying an html model for selling items by adapting existing code from a purchase model, while also explaining the necessary changes and providing the reasoning behind them.', 'duration': 478.735, 'highlights': ['The chapter details the process of creating bootstrap cards in HTML, including the code implementation and visual results. Creation of bootstrap cards, code implementation, visual results', 'Modifying an HTML model for selling items by adapting existing code from a purchase model, explaining the necessary changes and providing the reasoning behind them. Modification of HTML model, adaptation from purchase model, explanation of changes']}, {'end': 22267.181, 'start': 21987.734, 'title': 'Implementing model triggering in market.html', 'summary': 'Details the process of implementing a model trigger in market.html, including splitting the panes for easy understanding, changing the data target to a unique model per item, ensuring the modal is recognized as an html code, and using a trick to replace all variables with a specific text.', 'duration': 279.447, 'highlights': ['Splitting the panes for easy understanding and further changes in the implementation.', "Changing the data target to a unique model per item, such as 'owned_item'.", 'Ensuring the modal is recognized as an HTML code and implementing it inside the for loop for each item.', 'Using a trick to replace all variables with a specific text using the control F feature.']}, {'end': 22862.774, 'start': 22267.661, 'title': 'Implementing selling logic in routes.py', 'summary': "Details the process of implementing the selling logic in the routes.py file, including copying and pasting code, testing the functionality, and confirming the successful implementation, leading to the website's completion.", 'duration': 595.113, 'highlights': ['The process of implementing the selling logic in the routes.py file is detailed, including adding comments to differentiate between purchasing and selling item logic, copying and pasting code, and testing the functionality, ultimately leading to the completion of the website.', "The successful testing of the selling logic is confirmed, with the display of a congratulations message upon selling an item, updating the user's budget, and ensuring the availability of items on the market, indicating the flawless functionality of the implemented logic.", 'The importance of feedback for improving future series is emphasized, with a future episode planned to explain the deployment of a flask application to production, catering to a broader audience beyond the specific website project.']}], 'duration': 1459.293, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/Qr4QMBUPxWo/pics/Qr4QMBUPxWo21403481.jpg', 'highlights': ['The process of implementing the selling logic in the routes.py file is detailed, including adding comments to differentiate between purchasing and selling item logic, copying and pasting code, and testing the functionality, ultimately leading to the completion of the website.', "The successful testing of the selling logic is confirmed, with the display of a congratulations message upon selling an item, updating the user's budget, and ensuring the availability of items on the market, indicating the flawless functionality of the implemented logic.", 'The implementation involves using div classes and iterations to display available and owned items on the market, with a specific focus on organizing the layout using Bootstrap grid system and ensuring proper display of items in rows and columns.', "The div class is set to 'call-md-6' to ensure that items are displayed in rows of two, as the maximum size for an HTML element within a row is 12, providing a clear explanation for the choice of column size."]}], 'highlights': ['Flask allows quick and easy web application development with minimal code.', 'The series progresses from a minimal application to an advanced marketing system website.', 'The website aims to create a marketing system for buying and selling items.', 'The platform displays available items with name, barcode, and price, and introduces a budget system set at 15 grand.', "The system provides real-time updates on the user's budget and available items for an engaging e-commerce experience.", 'The command provided for setting up the environment works on Windows, Mac, and Linux distributions.', 'Emphasis on the importance of proper Python configuration, regardless of the IDE being used.', 'Flask routes determine the URLs in the website and the corresponding HTML code; the root URL leads to the homepage, and functions defined in routes are called views.', "Debug mode in Flask synchronizes code changes without requiring server restarts, enabling real-time code updates using 'flask run' command in debug mode.", "The convention in Flask is to create a 'templates' directory to store HTML files, and then refer routes to these HTML files, providing a clear structure for the project to enhance organization and maintenance.", 'The concept of template inheritance is introduced to avoid repetitive copying and pasting of HTML code for creating multiple pages, ultimately saving time and effort.', "Creating a 'name' column limited to 30 characters", 'Configuring the database by adding key values to the app object', 'The chapter covers the process of packaging a Python application, including setting up environment variables and checking if the run.py file has executed directly.', 'The need to store user information in a database is highlighted, with a focus on creating a new module for user information and defining fields such as username, email address, and password with specific constraints.', 'Setting up password field with a 60-character hash for data security.', 'Creating a registration form using Flask-WTF and WTForms packages', "Flask's 'flash' function replaces displaying errors in the web server's terminal.", 'The chapter details the process of updating the user registration form, including fixing validation errors, implementing hashed passwords for security, and installing Flask Bcrypt library to achieve this.', "The process involves creating a password property, setting up the password, using Bcrypt to generate password hash, and updating the route.py to handle hash passwords, ultimately resulting in successful implementation and verification of hash passwords for a new user, with the example of creating a new user 'JSC three' with a hashed password.", 'The chapter explains the process of creating a user login page, including designing a route, template, and form class, and ensuring proper functionality.', 'The chapter discusses the process of implementing the HTML logic in the registration form, creating a form HTML tag, and customizing the HTML page, aiming to provide a consistent user interface and improve the overall user experience.', "The dynamic property 'prettier_budget' was implemented in the base dot HTML, resulting in a website that displays a budget with dynamic formatting, allowing for future updates and purchases.", "The chapter covers configuring the logout functionality by adding a route to log out the user and redirecting to the homepage, as well as customizing the homepage by adding a logo and 'get started' button, with a link to the market page.", 'The market page display will be modified by dividing it into two main sections: available items and purchased items.', 'The process of importing HTML templates from separate files to ensure organized code structure and maintainability.', 'The process of customizing the purchase item model is similar to customizing the more info model, illustrating a consistent approach to model customization.', 'The chapter describes the process of updating modal and form fields to improve the user experience on the website.', "The prevention of resubmission output is accomplished by conditioning the execution of certain lines to only occur if the request type is 'get', ensuring that the confirm resubmission output is not displayed.", 'Implemented logic to prevent users from purchasing items if their budget is not enough, resulting in a successful prevention of overbudget purchases.', 'Querying owned items by the current user is implemented to facilitate the display of owned items in the market page, enhancing user experience.', 'The process of implementing the selling logic in the routes.py file is detailed, including adding comments to differentiate between purchasing and selling item logic, copying and pasting code, and testing the functionality, ultimately leading to the completion of the website.', "The successful testing of the selling logic is confirmed, with the display of a congratulations message upon selling an item, updating the user's budget, and ensuring the availability of items on the market, indicating the flawless functionality of the implemented logic."]}