WEBVTT

1
00:00:00.120 --> 00:00:02.759
<v Speaker 1>Welcome to the deep dive. You know, the next time

2
00:00:02.799 --> 00:00:05.320
<v Speaker 1>you load a web page, you aren't actually looking at

3
00:00:05.320 --> 00:00:06.320
<v Speaker 1>a document.

4
00:00:06.200 --> 00:00:07.919
<v Speaker 2>Right, definitely not a static document.

5
00:00:08.039 --> 00:00:09.880
<v Speaker 1>Yeah, it's more like you're looking at the result of

6
00:00:09.919 --> 00:00:16.800
<v Speaker 1>this high speed negotiation between dozens of separate systems, and

7
00:00:17.039 --> 00:00:18.480
<v Speaker 1>it's all happening in milliseconds.

8
00:00:18.519 --> 00:00:19.000
<v Speaker 2>It really is.

9
00:00:19.039 --> 00:00:21.039
<v Speaker 3>I mean, we tend to think of a website as

10
00:00:21.120 --> 00:00:24.760
<v Speaker 3>this finished magazine handed to us, but behind the screen,

11
00:00:24.920 --> 00:00:29.120
<v Speaker 3>it's a massive logistics operation assembling that magazine from scratch

12
00:00:29.320 --> 00:00:30.760
<v Speaker 3>every single time you click.

13
00:00:30.600 --> 00:00:32.560
<v Speaker 1>A link, which is wild to think about.

14
00:00:32.640 --> 00:00:32.799
<v Speaker 2>Oh.

15
00:00:32.840 --> 00:00:39.799
<v Speaker 3>Absolutely, it's incredibly complex orchestration of databases, server, logic, presentation layers,

16
00:00:40.159 --> 00:00:42.840
<v Speaker 3>and for anyone you know, standing on the outside looking in,

17
00:00:43.280 --> 00:00:47.119
<v Speaker 3>modern web architecture can seem totally impenetrable.

18
00:00:46.479 --> 00:00:49.280
<v Speaker 1>Because you have all these multiple languages and systems just

19
00:00:49.280 --> 00:00:50.799
<v Speaker 1>trying to talk to each other in a fraction of

20
00:00:50.840 --> 00:00:54.200
<v Speaker 1>a second. Exactly, Well, that is the exact complexity we're

21
00:00:54.200 --> 00:00:56.079
<v Speaker 1>going to clear up for you today. We're taking a

22
00:00:56.280 --> 00:00:59.799
<v Speaker 1>comprehensive journey into the anatomy of a modern web app,

23
00:01:00.039 --> 00:01:02.240
<v Speaker 1>and we're using the third edition of Jango three by

24
00:01:02.280 --> 00:01:05.319
<v Speaker 1>Example by Antonio Malea as our guide.

25
00:01:05.480 --> 00:01:08.480
<v Speaker 3>Which is a fantastic source because the material is just

26
00:01:08.640 --> 00:01:11.680
<v Speaker 3>highly practical. It strips away the abstract theory.

27
00:01:11.879 --> 00:01:14.560
<v Speaker 1>Yeah, it focuses entirely on how prorection grete apps are

28
00:01:14.560 --> 00:01:19.560
<v Speaker 1>actually built. So our mission today is to demystify this architecture.

29
00:01:19.680 --> 00:01:24.200
<v Speaker 3>Right, whether you're a seasoned coder or just someone who

30
00:01:24.239 --> 00:01:27.439
<v Speaker 3>wonders how your favorite sites work under the hood, we.

31
00:01:27.439 --> 00:01:30.239
<v Speaker 1>Want to break down that digital magic. And we aren't

32
00:01:30.280 --> 00:01:32.640
<v Speaker 1>just talking about a static web page with some text.

33
00:01:33.159 --> 00:01:35.359
<v Speaker 1>By the end of this conversation, we're going to unpack

34
00:01:35.439 --> 00:01:37.840
<v Speaker 1>how to build a fully dynamic.

35
00:01:37.439 --> 00:01:39.840
<v Speaker 2>Blog, a really robust one too, yeah.

36
00:01:39.719 --> 00:01:44.200
<v Speaker 1>Complete with an email sharing system, user comments, and a

37
00:01:44.239 --> 00:01:46.760
<v Speaker 1>smart recommendation engine that actually predicts what you want to

38
00:01:46.760 --> 00:01:47.480
<v Speaker 1>read next.

39
00:01:47.280 --> 00:01:49.319
<v Speaker 3>Which is where it gets really fun. But you know,

40
00:01:49.400 --> 00:01:51.680
<v Speaker 3>every ambitious build needs a blueprint first.

41
00:01:51.959 --> 00:01:52.280
<v Speaker 1>For sure.

42
00:01:52.319 --> 00:01:54.280
<v Speaker 3>We can't just start throwing code at a server and

43
00:01:54.319 --> 00:01:56.519
<v Speaker 3>expect it to hold up under traffic. You need an

44
00:01:56.640 --> 00:02:00.879
<v Speaker 3>organizational system, and in Django, that blueprintlies on a strict

45
00:02:00.920 --> 00:02:05.000
<v Speaker 3>division between the overall infrastructure and the specific functional components.

46
00:02:05.680 --> 00:02:08.240
<v Speaker 1>Right. The sources refer to these as projects and apps.

47
00:02:08.599 --> 00:02:10.240
<v Speaker 1>And I was reading this and I found the best

48
00:02:10.240 --> 00:02:12.120
<v Speaker 1>way to visualize. It is like city planning.

49
00:02:12.240 --> 00:02:12.960
<v Speaker 2>Okay, I like that.

50
00:02:13.439 --> 00:02:16.960
<v Speaker 1>So the Django project is the city grid. It's the

51
00:02:16.960 --> 00:02:20.039
<v Speaker 1>plot of land, the main water lines, the electrical grid,

52
00:02:20.120 --> 00:02:23.080
<v Speaker 1>all those global routing rules for the whole space. But

53
00:02:23.159 --> 00:02:26.639
<v Speaker 1>an app that's a specific building plugged into that grid.

54
00:02:26.479 --> 00:02:27.800
<v Speaker 2>Like a specialized structure.

55
00:02:27.960 --> 00:02:30.960
<v Speaker 1>Exactly, you might build a blog building or a forum building,

56
00:02:31.639 --> 00:02:36.240
<v Speaker 1>and because of this modular design, you could theoretically take

57
00:02:36.280 --> 00:02:39.080
<v Speaker 1>that fully functioning blog building, unplug it and drop it

58
00:02:39.120 --> 00:02:41.120
<v Speaker 1>into a totally different city grid later.

59
00:02:41.000 --> 00:02:45.520
<v Speaker 3>On, which is brilliant. Modularity is like the holy grail

60
00:02:45.840 --> 00:02:48.840
<v Speaker 3>of software engineering. It ensures you never have to build

61
00:02:48.879 --> 00:02:50.560
<v Speaker 3>the exact same functionality twice.

62
00:02:50.759 --> 00:02:50.960
<v Speaker 1>Right.

63
00:02:51.240 --> 00:02:54.199
<v Speaker 3>But within that specific building, your blog app, you need

64
00:02:54.240 --> 00:02:57.120
<v Speaker 3>a way to store data, and usually communicating with the

65
00:02:57.240 --> 00:02:59.560
<v Speaker 3>database means writing raw sequel.

66
00:02:59.319 --> 00:03:01.240
<v Speaker 1>Oh structured query language.

67
00:03:00.919 --> 00:03:02.479
<v Speaker 2>Yeah, which is a massive headache.

68
00:03:02.879 --> 00:03:06.000
<v Speaker 3>SQL can be brittle, it's hard to maintain, and it

69
00:03:06.080 --> 00:03:09.319
<v Speaker 3>locks your app to a specific database vendor like postgrest

70
00:03:09.319 --> 00:03:10.759
<v Speaker 3>school or my SQL.

71
00:03:10.960 --> 00:03:12.719
<v Speaker 1>So if you want to switch vendors later, you're just

72
00:03:12.759 --> 00:03:13.240
<v Speaker 1>out of luck.

73
00:03:13.319 --> 00:03:16.439
<v Speaker 3>Basically, yeah, you'd have to rewrite everything. But this is

74
00:03:16.479 --> 00:03:21.520
<v Speaker 3>where the framework introduces an object relational mapper or an ORM.

75
00:03:21.759 --> 00:03:25.840
<v Speaker 3>The ORM right, instead of writing raw sequel strings, developers

76
00:03:25.960 --> 00:03:29.479
<v Speaker 3>just write standard Python classes. The ORRM acts as this

77
00:03:29.639 --> 00:03:30.800
<v Speaker 3>universal translator.

78
00:03:30.840 --> 00:03:33.439
<v Speaker 1>I mean, the power that translator seems huge. You just

79
00:03:33.520 --> 00:03:36.680
<v Speaker 1>define a data model using Python variables exactly.

80
00:03:36.759 --> 00:03:39.199
<v Speaker 3>You say, hey, a title should be text with a

81
00:03:39.240 --> 00:03:43.840
<v Speaker 3>max length, or that a published date should automatically generate

82
00:03:43.879 --> 00:03:45.840
<v Speaker 3>a timestamp the second a record is.

83
00:03:45.800 --> 00:03:49.080
<v Speaker 1>Created and the text highlighted specific fields for that right, Yeah,

84
00:03:49.120 --> 00:03:51.599
<v Speaker 1>like charfield for the titles and date time field with

85
00:03:51.599 --> 00:03:53.400
<v Speaker 1>that autoo odd feature spot on.

86
00:03:53.639 --> 00:03:57.039
<v Speaker 3>That ORM takes all that Python logic and dynamically generates

87
00:03:57.039 --> 00:03:59.360
<v Speaker 3>the SEQL dialect for your specific database.

88
00:03:59.520 --> 00:03:59.800
<v Speaker 1>Wow.

89
00:04:00.039 --> 00:04:02.479
<v Speaker 3>So you could build your app using a tiny school

90
00:04:02.520 --> 00:04:05.120
<v Speaker 3>eight database on your laptop and then deploy it to

91
00:04:05.159 --> 00:04:09.199
<v Speaker 3>a massive enterprise Postgres school server without changing a single

92
00:04:09.319 --> 00:04:10.560
<v Speaker 3>line of your data logic.

93
00:04:10.639 --> 00:04:13.439
<v Speaker 1>See. I always worry about these abstraction layers like removing control,

94
00:04:13.599 --> 00:04:16.439
<v Speaker 1>but the RM actually adds nuance, like with the slug field.

95
00:04:16.680 --> 00:04:17.879
<v Speaker 2>Oh, the slugs are great.

96
00:04:17.959 --> 00:04:20.240
<v Speaker 1>Yeah. Instead of a database just assigning a random ID

97
00:04:20.360 --> 00:04:23.759
<v Speaker 1>number to a URL, the ORM enforces a system where

98
00:04:23.959 --> 00:04:27.439
<v Speaker 1>the title of your post is converted into like clean

99
00:04:27.600 --> 00:04:29.639
<v Speaker 1>readable text for the web address.

100
00:04:29.439 --> 00:04:31.160
<v Speaker 2>Which is essential for SEO.

101
00:04:31.759 --> 00:04:34.040
<v Speaker 1>But wait, this brings up a fundamental question for me.

102
00:04:34.399 --> 00:04:37.079
<v Speaker 1>If we're just typing Python classes in our code editor,

103
00:04:37.879 --> 00:04:41.959
<v Speaker 1>how does the actual SQL database know what to do?

104
00:04:42.839 --> 00:04:45.319
<v Speaker 1>How does it know to change its internal tables to

105
00:04:45.399 --> 00:04:46.199
<v Speaker 1>match our code?

106
00:04:46.480 --> 00:04:50.279
<v Speaker 3>Ah? Right, So that bridges us from the blueprint to

107
00:04:50.319 --> 00:04:53.360
<v Speaker 3>the actual construction, and that is handled by a system

108
00:04:53.439 --> 00:04:56.680
<v Speaker 3>called migrations. Migrations again, you can think of migrations as

109
00:04:56.879 --> 00:05:00.680
<v Speaker 3>version control for your database. Databases are super ridgid by nature.

110
00:05:01.079 --> 00:05:03.759
<v Speaker 3>If you tell a database a table has three columns,

111
00:05:03.839 --> 00:05:06.360
<v Speaker 3>and then later try to save a record with four columns,

112
00:05:06.560 --> 00:05:08.319
<v Speaker 3>it will throw a critical error.

113
00:05:08.079 --> 00:05:10.519
<v Speaker 1>And scheme has changed constantly. In the real world, I mean,

114
00:05:10.600 --> 00:05:13.399
<v Speaker 1>day one, your blog just has a title and a body.

115
00:05:13.920 --> 00:05:17.319
<v Speaker 1>Day one hundred marketing demands a subtitle, a header, image,

116
00:05:17.439 --> 00:05:20.639
<v Speaker 1>and an author bio. Modifying a live database sounds terrifying.

117
00:05:20.879 --> 00:05:24.519
<v Speaker 3>It is terrifying, which is exactly why Jango automates the

118
00:05:24.600 --> 00:05:28.040
<v Speaker 3>risk away. When you update your Python model, you run

119
00:05:28.040 --> 00:05:29.839
<v Speaker 3>a command called make migrations.

120
00:05:30.040 --> 00:05:31.040
<v Speaker 1>Okay, and what does that do?

121
00:05:31.319 --> 00:05:35.160
<v Speaker 3>It performs this highly complex calculation. It compares your new

122
00:05:35.199 --> 00:05:38.319
<v Speaker 3>Python code against the current state of the database. Calculates

123
00:05:38.319 --> 00:05:41.120
<v Speaker 3>the exact differences and writes out a precise set of

124
00:05:41.120 --> 00:05:42.759
<v Speaker 3>instructions to safely alter.

125
00:05:42.680 --> 00:05:45.920
<v Speaker 1>The tables without losing the existing data obviously exactly.

126
00:05:46.319 --> 00:05:50.000
<v Speaker 3>Then you run a second command, migrate to actually apply

127
00:05:50.040 --> 00:05:53.160
<v Speaker 3>those instructions. It totally takes the terror out of evolving

128
00:05:53.160 --> 00:05:53.600
<v Speaker 3>your app.

129
00:05:53.720 --> 00:05:56.279
<v Speaker 1>Okay, so once that data structure is solid, we run

130
00:05:56.279 --> 00:05:59.480
<v Speaker 1>into the content management problem because building a database is

131
00:05:59.480 --> 00:06:02.680
<v Speaker 1>one thing, but building a usable interface for editors to

132
00:06:02.720 --> 00:06:06.160
<v Speaker 1>actually type in articles that usually takes weeks of front

133
00:06:06.199 --> 00:06:06.639
<v Speaker 1>head work.

134
00:06:06.720 --> 00:06:07.720
<v Speaker 2>Oh easily weeks.

135
00:06:07.879 --> 00:06:11.079
<v Speaker 3>Yeah, but this is one of Jena's most famous magic features.

136
00:06:11.360 --> 00:06:14.600
<v Speaker 3>By just creating a super user and registering your Python model,

137
00:06:14.759 --> 00:06:18.959
<v Speaker 3>the framework dynamically generates a secure, production ready admin dashboard

138
00:06:19.199 --> 00:06:20.040
<v Speaker 3>entirely for free.

139
00:06:20.160 --> 00:06:22.240
<v Speaker 1>That's incredible. Just from reading the metadata.

140
00:06:22.519 --> 00:06:26.240
<v Speaker 3>Yeah, it knows exactly what type of data each field needs.

141
00:06:26.639 --> 00:06:29.839
<v Speaker 3>If you defined a date field, the dashboard automatically gives

142
00:06:29.839 --> 00:06:31.879
<v Speaker 3>you a JavaScript calendar widget.

143
00:06:31.959 --> 00:06:35.279
<v Speaker 1>Oh wow. And the customization options for that admin site

144
00:06:35.680 --> 00:06:41.800
<v Speaker 1>solve very real operational bottlenecks, like the prepopulated fields feature.

145
00:06:41.959 --> 00:06:42.759
<v Speaker 2>I love that one.

146
00:06:42.920 --> 00:06:45.560
<v Speaker 1>Right, as an editor types the title of a new article,

147
00:06:45.839 --> 00:06:49.800
<v Speaker 1>there's JavaScript running in the background. Automatically stripping out punctuation

148
00:06:50.399 --> 00:06:54.439
<v Speaker 1>and adding hyphens to generate that URL slug in real time.

149
00:06:54.560 --> 00:06:57.759
<v Speaker 3>It completely eliminates repetitive manual data entry.

150
00:06:57.879 --> 00:07:00.480
<v Speaker 1>And what about the rawed fields That was fascinating, right.

151
00:07:00.519 --> 00:07:03.319
<v Speaker 3>So imagine your blog allows guest authors and over a

152
00:07:03.360 --> 00:07:05.759
<v Speaker 3>few years you get fifty thousand registered users.

153
00:07:06.000 --> 00:07:06.360
<v Speaker 1>Okay.

154
00:07:06.600 --> 00:07:09.399
<v Speaker 3>A standard admin interface might try to render a drop

155
00:07:09.480 --> 00:07:11.639
<v Speaker 3>down menu so the editor can assign an author to

156
00:07:11.720 --> 00:07:12.160
<v Speaker 3>a post.

157
00:07:12.399 --> 00:07:15.759
<v Speaker 1>But forcing a browser to render fifty thousand HTML options

158
00:07:15.800 --> 00:07:16.879
<v Speaker 1>in one drop down.

159
00:07:16.720 --> 00:07:18.160
<v Speaker 2>It would instantly freeze the browser.

160
00:07:18.240 --> 00:07:19.120
<v Speaker 1>Yeah, complete memory.

161
00:07:19.199 --> 00:07:21.120
<v Speaker 2>It would crash their computer exactly.

162
00:07:21.560 --> 00:07:24.560
<v Speaker 3>So to fix that, you just add a rod fields

163
00:07:24.600 --> 00:07:28.279
<v Speaker 3>attribute in your Python can fig. It replaces that massive

164
00:07:28.360 --> 00:07:32.199
<v Speaker 3>drop down with a scalable search widget. The editor searches

165
00:07:32.240 --> 00:07:35.480
<v Speaker 3>a name, it queries the database and returns just the match.

166
00:07:35.680 --> 00:07:38.519
<v Speaker 1>It's just a tiny configuration change that prevents a massive

167
00:07:38.800 --> 00:07:42.000
<v Speaker 1>production failure exactly. Okay, so we have the database stabilized,

168
00:07:42.040 --> 00:07:44.680
<v Speaker 1>we have the admin dashboard. The next hurdle is showing

169
00:07:44.720 --> 00:07:47.120
<v Speaker 1>this to the public. We need to fetch the data

170
00:07:47.519 --> 00:07:50.519
<v Speaker 1>and present it the presentation layer. Yeah, and I like

171
00:07:50.560 --> 00:07:53.519
<v Speaker 1>to frame this like a restaurant. The URLU click is

172
00:07:53.560 --> 00:07:56.519
<v Speaker 1>the menu. The jingle view is the waiter taking your

173
00:07:56.519 --> 00:07:58.800
<v Speaker 1>request and running to the kitchen, which is the database

174
00:07:58.959 --> 00:08:01.160
<v Speaker 1>right right, and then the template is how the food

175
00:08:01.240 --> 00:08:02.639
<v Speaker 1>is plated and presented to you.

176
00:08:02.839 --> 00:08:05.439
<v Speaker 3>That's a great analogy, and the mechanics of how that

177
00:08:05.480 --> 00:08:09.120
<v Speaker 3>waiter communicates with the kitchen are super sophisticated. Django uses

178
00:08:09.160 --> 00:08:11.360
<v Speaker 3>this concept called lazy evaluation.

179
00:08:11.680 --> 00:08:14.319
<v Speaker 1>Lazy evaluation, what does that actually mean in practice?

180
00:08:14.399 --> 00:08:16.759
<v Speaker 3>So when a view needs data, it creates a query set.

181
00:08:17.240 --> 00:08:19.279
<v Speaker 3>Let's say you want to get all posts published in

182
00:08:19.319 --> 00:08:22.600
<v Speaker 3>twenty twenty six, written by a specific author and ordered

183
00:08:22.600 --> 00:08:23.120
<v Speaker 3>by date.

184
00:08:23.480 --> 00:08:26.000
<v Speaker 1>Okay, so if I write that as three separate filtering

185
00:08:26.040 --> 00:08:29.639
<v Speaker 1>commands in my code, does the system make three separate

186
00:08:29.680 --> 00:08:30.720
<v Speaker 1>trips to the database.

187
00:08:30.959 --> 00:08:32.639
<v Speaker 2>That's the beauty of lazy evaluation.

188
00:08:32.840 --> 00:08:33.360
<v Speaker 1>It doesn't.

189
00:08:33.480 --> 00:08:36.519
<v Speaker 3>When Python reads those filters, it evaluates them lazily. It

190
00:08:36.559 --> 00:08:37.960
<v Speaker 3>doesn't touch the database yet.

191
00:08:38.000 --> 00:08:39.519
<v Speaker 1>Wait, really, it just holds off.

192
00:08:39.639 --> 00:08:42.279
<v Speaker 3>Yeah. It basically acts as a holding pin building up

193
00:08:42.279 --> 00:08:45.679
<v Speaker 3>a complex sequel string in memory. It waits until the

194
00:08:45.759 --> 00:08:50.600
<v Speaker 3>absolute last possible millisecond. The database is only contacted when

195
00:08:50.639 --> 00:08:54.679
<v Speaker 3>the HTML template actively demands the data to draw the screen.

196
00:08:54.879 --> 00:08:57.639
<v Speaker 1>Wow, So it waits until the whole request is finalized, Yeah,

197
00:08:57.679 --> 00:09:01.519
<v Speaker 1>and then makes one single optimized trip to the kitchen.

198
00:09:01.240 --> 00:09:05.320
<v Speaker 3>Exactly, which dramatically reduces network overhead and saves so much

199
00:09:05.360 --> 00:09:06.000
<v Speaker 3>server memory.

200
00:09:06.120 --> 00:09:08.879
<v Speaker 1>So once that data comes back, the view hands it

201
00:09:08.879 --> 00:09:11.559
<v Speaker 1>to the template, and the template uses its own language,

202
00:09:11.639 --> 00:09:13.480
<v Speaker 1>right with s pacific tags and filters.

203
00:09:13.559 --> 00:09:16.320
<v Speaker 3>Yeah, it uses tags like percent for percent loops to

204
00:09:16.399 --> 00:09:17.440
<v Speaker 3>iterate through the posts.

205
00:09:17.480 --> 00:09:19.919
<v Speaker 1>And it creates a strict separation of concerns like you

206
00:09:19.960 --> 00:09:23.879
<v Speaker 1>don't want back at engineers mixing Python logic inside HTML files.

207
00:09:24.000 --> 00:09:26.159
<v Speaker 2>No, that gets incredibly messy, and.

208
00:09:26.440 --> 00:09:28.600
<v Speaker 1>You don't want front end designers having to read database

209
00:09:28.679 --> 00:09:30.360
<v Speaker 1>queries just to change a fond color.

210
00:09:30.480 --> 00:09:33.120
<v Speaker 3>Right, So the template language acts as a bridge. A

211
00:09:33.159 --> 00:09:37.000
<v Speaker 3>designer can apply presentation filters directly in the HTML, like

212
00:09:37.120 --> 00:09:41.159
<v Speaker 3>using a truncatewords dot zero filter so only the first

213
00:09:41.279 --> 00:09:44.639
<v Speaker 3>thirty words of an article show up on the homepage.

214
00:09:44.200 --> 00:09:47.320
<v Speaker 1>Or using the line breaks filter to automatically turn plaintext

215
00:09:47.440 --> 00:09:50.039
<v Speaker 1>into proper HTML paragraphs exactly.

216
00:09:50.120 --> 00:09:52.600
<v Speaker 3>It lets the front end and back end teams work

217
00:09:52.679 --> 00:09:55.399
<v Speaker 3>in parallel without stepping on each other's toes.

218
00:09:55.639 --> 00:09:58.919
<v Speaker 1>So all this gives us a really fast, efficient digital brochure.

219
00:10:00.000 --> 00:10:03.000
<v Speaker 1>Honored users want interactivity right, they want to comment on things,

220
00:10:03.039 --> 00:10:04.039
<v Speaker 1>they want to share things.

221
00:10:04.080 --> 00:10:05.279
<v Speaker 2>They expect a two way street.

222
00:10:05.440 --> 00:10:07.960
<v Speaker 1>Yeah. So to transition from a read only site to

223
00:10:08.000 --> 00:10:10.639
<v Speaker 1>an interactive app, we have to introduce forms, right.

224
00:10:10.679 --> 00:10:12.559
<v Speaker 3>And to understand forms, you have to remember that the

225
00:10:12.679 --> 00:10:16.559
<v Speaker 3>HTTP protocol is fundamentally stateless.

226
00:10:16.080 --> 00:10:18.320
<v Speaker 1>Meaning every request is totally independent.

227
00:10:18.480 --> 00:10:20.960
<v Speaker 3>Exactly, when a user clicks a button to share an

228
00:10:21.039 --> 00:10:25.120
<v Speaker 3>article via email, their browser sends a standard GAT request.

229
00:10:25.320 --> 00:10:28.679
<v Speaker 3>The server sees that GDT method and responds by delivering

230
00:10:28.720 --> 00:10:30.200
<v Speaker 3>an empty HTML form.

231
00:10:30.480 --> 00:10:33.360
<v Speaker 1>Okay. Then the user fills out their friend's email address

232
00:10:33.559 --> 00:10:36.480
<v Speaker 1>where it's a quick message and hit submit. Now the

233
00:10:36.480 --> 00:10:40.320
<v Speaker 1>browser shifts tactics and sends a post request.

234
00:10:39.960 --> 00:10:43.720
<v Speaker 3>Right, and that post request packages all the users typed

235
00:10:43.840 --> 00:10:46.879
<v Speaker 3>data into the payload. The server catches it, runs it

236
00:10:46.879 --> 00:10:49.159
<v Speaker 3>through a validation process to make sure that emails are

237
00:10:49.159 --> 00:10:53.000
<v Speaker 3>actually formatted correctly and ensures no malicious code is hidden

238
00:10:53.000 --> 00:10:53.360
<v Speaker 3>in there.

239
00:10:53.600 --> 00:10:56.720
<v Speaker 1>And the book outlines two different strategies for this inbound data.

240
00:10:57.039 --> 00:11:00.960
<v Speaker 1>The email sharing feature uses a standard form, It validates

241
00:11:01.000 --> 00:11:04.480
<v Speaker 1>the input, connects fro an SMTP server like Gmail, dispatches

242
00:11:04.519 --> 00:11:07.120
<v Speaker 1>the email, and then just discards the data.

243
00:11:07.240 --> 00:11:09.600
<v Speaker 3>Right, Because we don't need to save those emails. But

244
00:11:09.679 --> 00:11:12.600
<v Speaker 3>a user comment is different. A comment is persistent data

245
00:11:12.639 --> 00:11:14.759
<v Speaker 3>that has to be saved into our database blueprint.

246
00:11:14.879 --> 00:11:16.360
<v Speaker 1>So for that they use a model form.

247
00:11:16.519 --> 00:11:18.000
<v Speaker 2>Yes, the model form is brilliant.

248
00:11:18.080 --> 00:11:21.519
<v Speaker 1>It seems like it eliminates an enormous amount of boilerplate code,

249
00:11:21.720 --> 00:11:25.279
<v Speaker 1>Like instead of manually writing htmail inputs for a name, email,

250
00:11:25.320 --> 00:11:28.440
<v Speaker 1>and the comment body, the model form just introspects the

251
00:11:28.480 --> 00:11:30.960
<v Speaker 1>existing database schema right exactly.

252
00:11:31.000 --> 00:11:33.519
<v Speaker 3>It looks at your comment model sees exactly what fields

253
00:11:33.519 --> 00:11:37.559
<v Speaker 3>are required and generates the exact htmail form for you automatically.

254
00:11:38.039 --> 00:11:40.720
<v Speaker 3>Plus it handles the validation and saving it straight to

255
00:11:40.759 --> 00:11:41.399
<v Speaker 3>the database.

256
00:11:41.519 --> 00:11:46.000
<v Speaker 1>It's a huge time saver. But opening your server to

257
00:11:46.080 --> 00:11:51.320
<v Speaker 1>receive data from the public Internet that introduces severe security vulnerabilities.

258
00:11:51.360 --> 00:11:54.039
<v Speaker 3>Oh absolutely, Whenever you implement a form, you have to

259
00:11:54.080 --> 00:11:57.840
<v Speaker 3>defend against cross site request forgery or CSRF.

260
00:11:57.960 --> 00:12:00.600
<v Speaker 1>CSRF. Let's break down the mechanics of that attack, because

261
00:12:00.600 --> 00:12:05.039
<v Speaker 1>it's pretty devious. Say I'm logged into my secure banking portal. Okay,

262
00:12:05.159 --> 00:12:08.440
<v Speaker 1>so my browser has an active authenticated session cookie for

263
00:12:08.480 --> 00:12:10.799
<v Speaker 1>the bank. Then I open a new tab and click

264
00:12:10.840 --> 00:12:13.000
<v Speaker 1>a malicious link on some random form.

265
00:12:13.000 --> 00:12:15.399
<v Speaker 2>Right, and that malicious site has a hidden script.

266
00:12:15.519 --> 00:12:18.600
<v Speaker 1>Yeah, a script that automatically sends a POSC request to

267
00:12:18.759 --> 00:12:22.200
<v Speaker 1>my bank's form demanding a money transfer. And because my

268
00:12:22.200 --> 00:12:25.799
<v Speaker 1>browser automatically attaches my active banking cookie to the request,

269
00:12:26.200 --> 00:12:28.120
<v Speaker 1>the bank just assumes I authorized it.

270
00:12:28.120 --> 00:12:31.480
<v Speaker 3>It's forging a request across different domains by exploiting the

271
00:12:31.480 --> 00:12:32.960
<v Speaker 3>browser's automatic cookies.

272
00:12:33.080 --> 00:12:34.759
<v Speaker 1>Right. So how does Django stop that.

273
00:12:35.120 --> 00:12:38.639
<v Speaker 3>It acts like a VIP bouncer. It implements a cryptographic

274
00:12:38.679 --> 00:12:42.360
<v Speaker 3>defense mechanism. When the server generates a legitimate form for

275
00:12:42.440 --> 00:12:45.879
<v Speaker 3>a user, it creates a highly complex randomized string of

276
00:12:45.919 --> 00:12:50.159
<v Speaker 3>characters called a CSRF token. It hides this token inside

277
00:12:50.159 --> 00:12:52.840
<v Speaker 3>a hidden field in the HTML form and stores a

278
00:12:52.879 --> 00:12:54.120
<v Speaker 3>matching value on the server.

279
00:12:54.240 --> 00:12:56.039
<v Speaker 1>So it's like a cryptographic pairing.

280
00:12:56.000 --> 00:12:59.120
<v Speaker 3>Exactly like a vault mechanism, requiring two keys to turn

281
00:12:59.159 --> 00:13:01.879
<v Speaker 3>at the same time. When you submit the form, the

282
00:13:01.919 --> 00:13:04.879
<v Speaker 3>server checks the payload for that hidden token, and.

283
00:13:04.960 --> 00:13:07.720
<v Speaker 1>If a malicious site tries to forge your request, it

284
00:13:07.759 --> 00:13:09.799
<v Speaker 1>won't have that randomized token, right.

285
00:13:09.679 --> 00:13:12.480
<v Speaker 3>And the server will just instantly reject the payload. And

286
00:13:12.519 --> 00:13:15.240
<v Speaker 3>the best part is as long as the developer includes

287
00:13:15.279 --> 00:13:18.440
<v Speaker 3>the percent SERF token percent tag in their template, Jango

288
00:13:18.559 --> 00:13:22.240
<v Speaker 3>handles this entire cryptographic handshake automatically.

289
00:13:21.840 --> 00:13:26.120
<v Speaker 1>Providing that robust security by default is so critical. So okay,

290
00:13:26.279 --> 00:13:29.120
<v Speaker 1>we have secure interactive data flowing in. Now we can

291
00:13:29.240 --> 00:13:31.480
<v Speaker 1>leverage that data to make the site smart.

292
00:13:31.600 --> 00:13:35.120
<v Speaker 3>Yes, moving from just storing information to actually analyzing it.

293
00:13:35.320 --> 00:13:39.679
<v Speaker 1>Right, building the recommendation engine. The goal here is intelligent prediction.

294
00:13:40.120 --> 00:13:42.840
<v Speaker 1>If someone finishes reading a deep dive on jazz history,

295
00:13:43.159 --> 00:13:46.720
<v Speaker 1>we want to dynamically suggest other articles they'd like, right,

296
00:13:47.039 --> 00:13:50.279
<v Speaker 1>and to do that we need a categorization structure. The

297
00:13:50.320 --> 00:13:53.080
<v Speaker 1>book adds a third party app called Jango tag it

298
00:13:53.279 --> 00:13:54.600
<v Speaker 1>to build a tagging.

299
00:13:54.240 --> 00:13:57.480
<v Speaker 3>System which introduces many to many relationship.

300
00:13:57.759 --> 00:14:00.320
<v Speaker 1>Right. Because a comment has a one to many relationship,

301
00:14:00.120 --> 00:14:03.960
<v Speaker 1>it belongs to one specific article. But tags operate in

302
00:14:04.000 --> 00:14:04.639
<v Speaker 1>a web.

303
00:14:04.600 --> 00:14:07.600
<v Speaker 3>Exactly the tag jazz can be on fifty different articles,

304
00:14:07.600 --> 00:14:09.960
<v Speaker 3>and one article can have a dozen different tags.

305
00:14:10.200 --> 00:14:13.279
<v Speaker 1>So how do we actually query that overlapping web to

306
00:14:13.320 --> 00:14:14.279
<v Speaker 1>get recommendations?

307
00:14:14.360 --> 00:14:17.440
<v Speaker 3>It's a masterclass in data aggregation. The server has to

308
00:14:17.519 --> 00:14:21.639
<v Speaker 3>execute a multi layered query. Step one is identification. We

309
00:14:21.679 --> 00:14:24.600
<v Speaker 3>get the database to isolate the exact ideas of every

310
00:14:24.639 --> 00:14:25.759
<v Speaker 3>tag on the current article.

311
00:14:25.799 --> 00:14:28.639
<v Speaker 1>Okay, so that establishes our baseline. Say the article has

312
00:14:28.679 --> 00:14:31.200
<v Speaker 1>the tags music, history, and New Orleans.

313
00:14:31.279 --> 00:14:35.320
<v Speaker 3>Right, then step two is gathering candidates. We query the

314
00:14:35.320 --> 00:14:37.840
<v Speaker 3>whole database for any article that shares at least one

315
00:14:37.879 --> 00:14:39.080
<v Speaker 3>of those baseline tags.

316
00:14:39.360 --> 00:14:42.879
<v Speaker 1>But logic dictates we have to exclude the current article

317
00:14:42.919 --> 00:14:46.679
<v Speaker 1>from that pool, right, Otherwise it would just enthusiastically recommend

318
00:14:46.879 --> 00:14:48.919
<v Speaker 1>the exact article they just finish reading.

319
00:14:48.879 --> 00:14:51.360
<v Speaker 3>Exactly because it's a perfect match for its own tags.

320
00:14:51.440 --> 00:14:53.120
<v Speaker 3>So we apply an exclusion command.

321
00:14:53.279 --> 00:14:56.440
<v Speaker 1>Got it, But now we have this massive pool of

322
00:14:56.840 --> 00:15:00.799
<v Speaker 1>related articles and they're totally unranked. An article with one

323
00:15:00.879 --> 00:15:03.600
<v Speaker 1>matching tag has the same weight as an article with

324
00:15:03.679 --> 00:15:04.559
<v Speaker 1>three matching.

325
00:15:04.279 --> 00:15:07.600
<v Speaker 3>Tags, which is where step four comes in. We introduce

326
00:15:07.639 --> 00:15:11.799
<v Speaker 3>a scoring system. We instruct the database to use account

327
00:15:11.799 --> 00:15:15.879
<v Speaker 3>aggregation function okay, for every single article in the candidate pool,

328
00:15:15.960 --> 00:15:18.960
<v Speaker 3>the database calculates a numerical count of how many tags

329
00:15:19.000 --> 00:15:20.559
<v Speaker 3>it shares with our baseline, and.

330
00:15:20.519 --> 00:15:23.559
<v Speaker 1>Then we sort the pool descending by that mathematical score.

331
00:15:23.720 --> 00:15:27.600
<v Speaker 3>Yes, and if two articles share exactly two tags, we

332
00:15:27.679 --> 00:15:30.360
<v Speaker 3>need a tiebreaker, so we use the published date to

333
00:15:30.399 --> 00:15:31.679
<v Speaker 3>prioritize the newer one.

334
00:15:31.840 --> 00:15:34.960
<v Speaker 1>Makes sense, So the final phase is optimization, because we

335
00:15:35.039 --> 00:15:37.759
<v Speaker 1>only want to show say, four recommendations on the screen.

336
00:15:37.960 --> 00:15:40.759
<v Speaker 1>We could just pull the entire sorted pool into the

337
00:15:40.759 --> 00:15:44.200
<v Speaker 1>Python server's memory and grab the first four. But if

338
00:15:44.240 --> 00:15:47.279
<v Speaker 1>our site has ten thousand related articles.

339
00:15:46.919 --> 00:15:49.440
<v Speaker 3>Oh, dragging all ten thousand records across the network just

340
00:15:49.480 --> 00:15:52.320
<v Speaker 3>to throw away nine nine and ninety six of them,

341
00:15:52.480 --> 00:15:54.639
<v Speaker 3>that is a massive architectural failure.

342
00:15:54.720 --> 00:15:56.240
<v Speaker 1>Yeah, huge waste ARAM.

343
00:15:56.039 --> 00:15:59.159
<v Speaker 3>Which is why the orum translates our slicing instruction into

344
00:15:59.200 --> 00:16:02.799
<v Speaker 3>a SEQL limit clb Oh nice. Yeah, the database does

345
00:16:02.840 --> 00:16:05.519
<v Speaker 3>all the heavy lifting, sorts the massive data set internally

346
00:16:05.559 --> 00:16:08.960
<v Speaker 3>and only transmits exactly four records back over the network.

347
00:16:09.240 --> 00:16:13.480
<v Speaker 1>The elegance of that is just remarkable because of lazy evaluation,

348
00:16:13.720 --> 00:16:19.279
<v Speaker 1>the identification gathering, exclusion, aggregation, sorting, and slicing, it's all

349
00:16:19.279 --> 00:16:22.600
<v Speaker 1>compiled into one singular, highly optimized query.

350
00:16:22.840 --> 00:16:25.919
<v Speaker 3>It transforms a really complex analytical challenge into just a

351
00:16:26.000 --> 00:16:27.639
<v Speaker 3>few lines of efficient code.

352
00:16:27.840 --> 00:16:31.200
<v Speaker 1>So, looking back at everything we've explored today, the journey

353
00:16:31.200 --> 00:16:33.799
<v Speaker 1>from an empty server to a dynamic app is profound.

354
00:16:34.039 --> 00:16:34.679
<v Speaker 2>It really is.

355
00:16:34.960 --> 00:16:38.000
<v Speaker 1>We established a modular blueprint with projects and abs. We

356
00:16:38.039 --> 00:16:41.279
<v Speaker 1>bypassed Britle sqel using the RM and safely evolved our

357
00:16:41.320 --> 00:16:43.120
<v Speaker 1>schema with migrations.

358
00:16:42.879 --> 00:16:46.840
<v Speaker 3>We saw how lazy evaluation acts as this highly efficient

359
00:16:47.159 --> 00:16:48.720
<v Speaker 3>just in time supply chain.

360
00:16:48.799 --> 00:16:51.279
<v Speaker 1>Right, and we set up a strict separation of concerns

361
00:16:51.320 --> 00:16:53.879
<v Speaker 1>with views and templates. We opened a two way street

362
00:16:53.879 --> 00:16:57.200
<v Speaker 1>with model forms, secured it with CSRF tokens.

363
00:16:56.759 --> 00:17:00.120
<v Speaker 3>And finally navigated many to many relationships to build an

364
00:17:00.159 --> 00:17:02.039
<v Speaker 3>intelligent recommendation engine.

365
00:17:02.440 --> 00:17:05.559
<v Speaker 1>We really deconstructed the whole digital logistics operation from the

366
00:17:05.559 --> 00:17:06.440
<v Speaker 1>ground up. We did.

367
00:17:07.039 --> 00:17:09.079
<v Speaker 3>But you know, before we wrap up, I want to

368
00:17:09.160 --> 00:17:11.680
<v Speaker 3>leave you with a thought about how these exact mechanics

369
00:17:11.680 --> 00:17:14.880
<v Speaker 3>apply outside the web. Okay, we analyzed many to many

370
00:17:14.960 --> 00:17:19.079
<v Speaker 3>data aggregation to recommend digital articles, right, but think about

371
00:17:19.079 --> 00:17:23.000
<v Speaker 3>the physical world. Consider the logistics of an Amazon warehouse.

372
00:17:23.200 --> 00:17:25.960
<v Speaker 1>Oh wow, moving physical boxes instead of digital text.

373
00:17:26.160 --> 00:17:26.680
<v Speaker 2>Exactly.

374
00:17:26.920 --> 00:17:30.960
<v Speaker 3>The underlying logic is virtually identical. A massive warehouse relies

375
00:17:30.960 --> 00:17:34.400
<v Speaker 3>on these exact same data structures. A specific book isn't

376
00:17:34.440 --> 00:17:37.599
<v Speaker 3>just sitting on a shelf. It's dynamically tagged with data

377
00:17:37.680 --> 00:17:41.759
<v Speaker 3>about purchase frequency, geographical demand, associated items.

378
00:17:41.960 --> 00:17:44.759
<v Speaker 1>So when the system aggregates those tags, it's not recommending

379
00:17:44.799 --> 00:17:48.440
<v Speaker 1>a web page. It's predicting physical movement exactly.

380
00:17:48.799 --> 00:17:52.519
<v Speaker 3>It's instructing an automated forklift to move that specific book

381
00:17:52.559 --> 00:17:55.160
<v Speaker 3>closer to the loading docks on a Tuesday. Because the

382
00:17:55.279 --> 00:17:59.240
<v Speaker 3>database aggregation predicts a high probability of an order coming

383
00:17:59.279 --> 00:18:02.440
<v Speaker 3>from a specific zip code based on overlapping tags.

384
00:18:02.599 --> 00:18:05.480
<v Speaker 1>That is mind blowing. The code architecture we unpack today

385
00:18:05.519 --> 00:18:09.400
<v Speaker 1>isn't just rendering websites. It's literally dictating the physical movement

386
00:18:09.400 --> 00:18:13.319
<v Speaker 1>of goods across the planet before a human even clicks purchase.

387
00:18:13.559 --> 00:18:18.359
<v Speaker 3>The database aggregation dictates physical reality. The logistics operation never stops.

388
00:18:18.480 --> 00:18:20.400
<v Speaker 1>Well, that is a perfect place to end it. Thank

389
00:18:20.440 --> 00:18:23.160
<v Speaker 1>you for joining us on this deep dive. Keep questioning

390
00:18:23.200 --> 00:18:25.440
<v Speaker 1>how the infrastructure around you is built, and we will

391
00:18:25.440 --> 00:18:26.200
<v Speaker 1>see you next time.
