1
00:00:05,470 --> 00:00:09,670
Welcome back, everyone, to this lecture on jingo form, widgets and styling.

2
00:00:11,260 --> 00:00:18,550
Recall that inside the actual forms, that pie form class, we have the form fields and those are all

3
00:00:18,550 --> 00:00:25,540
connected to generating a single widget that in turn is actually what's rendering the HTML form input

4
00:00:25,540 --> 00:00:26,530
and label text.

5
00:00:26,980 --> 00:00:32,920
So if I wanted more specific control over styling and presentation of our actual form, we can access

6
00:00:32,920 --> 00:00:34,000
the widget attributes.

7
00:00:34,300 --> 00:00:39,790
This gives us a lot more detail level control on the Python side of things without again needing to

8
00:00:39,790 --> 00:00:41,440
worry on the HTML template.

9
00:00:43,320 --> 00:00:48,420
We're going to begin by linking a static files directory to hold our custom CSC files.

10
00:00:48,990 --> 00:00:54,810
The general steps for this is to first actually create our static folder inside our application.

11
00:00:55,080 --> 00:00:59,400
Then a sub directory again with the same application name and then create our CSV file.

12
00:00:59,850 --> 00:01:02,640
Then we can load the static directory in the HTML template.

13
00:01:02,910 --> 00:01:08,860
We'll link the static csv file within an ref and then we run migrate to load the new app in settings

14
00:01:08,860 --> 00:01:09,390
about pie.

15
00:01:09,660 --> 00:01:11,310
Let's check this all out and our editor.

16
00:01:12,120 --> 00:01:14,730
All right, here we are back inside a visual studio code.

17
00:01:15,150 --> 00:01:21,840
What I'm going to do is create that static file and then connect it to my actual HTML code.

18
00:01:22,290 --> 00:01:29,460
So I'm going to open up my explorer here and underneath cars, just like I have templates, cars, I'm

19
00:01:29,460 --> 00:01:31,350
going to create a new folder.

20
00:01:32,270 --> 00:01:36,080
Call it static and then create a new folder.

21
00:01:36,260 --> 00:01:42,170
Beyond that called cars, so it's a subdirectory, so goes cars, static cars just like you have cars,

22
00:01:42,170 --> 00:01:48,650
templates, cars and inside this static cars folder is where I can then create a new file and call that

23
00:01:49,010 --> 00:01:51,080
my custom CSV file.

24
00:01:51,710 --> 00:01:53,600
OK, so we have our custom CSS.

25
00:01:54,110 --> 00:01:57,230
And then what we're going to do is just create a very simple class here.

26
00:01:57,290 --> 00:02:03,650
So we'll say my form and I'm going to have this be a border, so I have my form class.

27
00:02:04,070 --> 00:02:10,009
This is going to be a border, and let's make this five pixels dashed red.

28
00:02:10,100 --> 00:02:12,860
So it's really obvious that it's actually being stylized.

29
00:02:14,240 --> 00:02:19,850
So then you have your customs scissors, but how do you actually link this static file to your HTML?

30
00:02:20,300 --> 00:02:24,410
Well, you can just come to your HTML and let me collapse explorer now.

31
00:02:25,100 --> 00:02:30,260
So come to your HTML and at the very top of it, you need to make the connection to load static with

32
00:02:30,470 --> 00:02:34,070
curly braces, percent sign and then load space.

33
00:02:34,640 --> 00:02:39,410
Static that essentially says that it's going to begin loading files from the static directory.

34
00:02:39,800 --> 00:02:45,350
Keep in mind that static directory is also defined here in settings that pie.

35
00:02:45,410 --> 00:02:51,140
So if you go to settings that pie in the same way that you have the installed apps configuration there,

36
00:02:51,620 --> 00:02:56,330
that also needs to happen later on, we'll see that we need to run migrations so you connect the app

37
00:02:56,570 --> 00:02:58,490
and then later on, that will actually connect.

38
00:02:58,490 --> 00:03:03,770
Just like we have app directories or templates, you scroll all the way down and you actually see there's

39
00:03:03,770 --> 00:03:04,760
a static URL.

40
00:03:05,120 --> 00:03:10,220
There's more information here at this link how to static files but it's essentially a way to link things

41
00:03:10,220 --> 00:03:12,590
like your CSIS, your JavaScript or your images.

42
00:03:12,950 --> 00:03:16,370
OK, so that's how that's all being done automatically from the settings.

43
00:03:16,790 --> 00:03:22,010
So once you load up your static, you can actually call files with static.

44
00:03:22,790 --> 00:03:26,160
So the way that works is inside your HTML.

45
00:03:26,160 --> 00:03:30,950
What we're going to do is just make a new CSIS reference link.

46
00:03:31,370 --> 00:03:34,910
So I'm going to say, let me make a couple of spaces here inside the head.

47
00:03:35,510 --> 00:03:36,350
A new link.

48
00:03:36,890 --> 00:03:37,970
It'll be a style sheet.

49
00:03:38,450 --> 00:03:44,750
And then my h ref is going to be inside curly braces here.

50
00:03:45,890 --> 00:03:48,920
Percent signs, and then I'm going to say static.

51
00:03:50,090 --> 00:03:55,220
And then, let's say cars forward slash custom, that CSIS.

52
00:03:55,760 --> 00:03:59,930
OK, so this says look in the static directory and then load this up.

53
00:04:00,290 --> 00:04:04,400
Similar to kind of connecting to a template with URL names.

54
00:04:04,580 --> 00:04:09,590
So I have to load static and then I can call things like static passing the file name.

55
00:04:09,980 --> 00:04:14,030
So now I should have linked my style sheets to make sure this is working.

56
00:04:14,040 --> 00:04:18,620
Let's go ahead and pass in for this entire div that we have here.

57
00:04:19,339 --> 00:04:22,180
The My Form class save those changes.

58
00:04:22,190 --> 00:04:27,140
That should be kind of obvious if it actually worked or not, because we should see a giant dashed red

59
00:04:27,140 --> 00:04:31,430
line there with a border to actually register the static file.

60
00:04:31,430 --> 00:04:38,480
What to do is, say, python managed pie and then migrates.

61
00:04:38,810 --> 00:04:42,170
I already actually ran migrations earlier before I recorded this.

62
00:04:42,500 --> 00:04:46,910
So you will see a bunch of stuff come out, but I don't see anything, so I'm good to go there.

63
00:04:47,270 --> 00:04:49,130
Let's now actually run the website.

64
00:04:49,130 --> 00:04:52,870
So Python managed our pie run server.

65
00:04:53,890 --> 00:05:01,210
And upon running that server, when you refresh your rental form, you should see this really obvious

66
00:05:01,210 --> 00:05:02,320
red border around it.

67
00:05:02,890 --> 00:05:09,310
OK, so we just discovered how to create our own static files and load them with static calls inside

68
00:05:09,310 --> 00:05:09,970
each HTML.

69
00:05:10,450 --> 00:05:12,400
Now we haven't actually explored widgets yet.

70
00:05:12,550 --> 00:05:17,740
For example, what if I only wanted a red border around the email field?

71
00:05:17,920 --> 00:05:18,580
How could I do that?

72
00:05:19,510 --> 00:05:24,580
One way you could do it is manually inside the actual HTML code.

73
00:05:24,940 --> 00:05:28,780
I could, instead of a for loop here, write out each individual field.

74
00:05:28,780 --> 00:05:33,790
And then when I got to a particular field, I would make a div call and on that particular, they've

75
00:05:34,270 --> 00:05:36,160
and in the class for my form.

76
00:05:36,490 --> 00:05:42,820
However, we want to try to put most of the work on Django and Python instead of having kind of these

77
00:05:43,450 --> 00:05:46,690
gargantuan HTML files that are harder to read sometimes.

78
00:05:47,140 --> 00:05:54,820
So the way that works is you come to forms that pie and you can recall that each field has these arguments

79
00:05:54,820 --> 00:05:55,550
you can pass in.

80
00:05:55,570 --> 00:05:57,460
And one of the arguments is widget.

81
00:05:57,940 --> 00:06:03,250
So if you check out the documentation on form fields, so if you just Google, search Django Docs,

82
00:06:03,250 --> 00:06:10,210
form fields and you come to form fields, eventually you realize that each of the form fields have core

83
00:06:10,210 --> 00:06:16,450
field arguments, such as label or whether or not that field is required or the widget.

84
00:06:17,440 --> 00:06:22,240
So each particular field comes with a widget, and that's actually an argument.

85
00:06:22,570 --> 00:06:26,740
There's the default widgets, but we can see that some of them sometimes don't make sense for what we're

86
00:06:26,740 --> 00:06:29,530
looking for, such as Please write your review here.

87
00:06:29,920 --> 00:06:34,750
The text input widget probably isn't so great, because if I want to put a paragraph of information

88
00:06:34,750 --> 00:06:38,290
here, eventually I'm starting to run out of space and I don't get something nice.

89
00:06:38,590 --> 00:06:44,050
Well, it's probably better as a text area input, and that's done through the widget, so you can click

90
00:06:44,050 --> 00:06:46,330
here to see the widgets that are available for you.

91
00:06:47,360 --> 00:06:52,400
So then when you go to the widgets section of the documentation, you get to see all the built in widgets,

92
00:06:52,410 --> 00:07:00,350
there's text input, no input, email input, there's text area, selection boxes, multiple billions,

93
00:07:00,350 --> 00:07:03,500
file inputs, calendars, etc. So tons of stuff.

94
00:07:03,920 --> 00:07:06,050
And what I'm going to do is check up text area.

95
00:07:07,150 --> 00:07:12,940
So I can see here this will actually generate a text area for us, which means I can override this by

96
00:07:12,940 --> 00:07:16,780
just creating a text area inside the widgets.

97
00:07:17,170 --> 00:07:18,580
So let's come back here.

98
00:07:19,090 --> 00:07:21,400
I see Form's character field.

99
00:07:21,940 --> 00:07:30,730
I'm going to add in a new argument here, which will be widget, and then I'm going to assign that widget

100
00:07:30,760 --> 00:07:35,290
and let me enter here just to get a little more space for readability.

101
00:07:35,920 --> 00:07:36,250
OK.

102
00:07:36,640 --> 00:07:39,190
So I have widget and it's going to be equal to.

103
00:07:40,510 --> 00:07:48,760
A text area from forms, so we simply say which is equal to forms dot and then the name of that particular

104
00:07:48,760 --> 00:07:53,890
widget like text area, open close parentheses there safe that.

105
00:07:54,010 --> 00:07:58,090
And you should now see when you refresh your rental review form.

106
00:07:58,840 --> 00:07:59,660
Refresh that.

107
00:07:59,680 --> 00:08:02,530
This is now a text area here.

108
00:08:03,280 --> 00:08:04,990
OK, so so far, so good.

109
00:08:04,990 --> 00:08:09,520
We were able to change this to a text area that makes it a lot more sense for writing a review.

110
00:08:09,970 --> 00:08:16,270
Technically speaking, you could overwrite the default widgets for any of these attributes, but often

111
00:08:16,270 --> 00:08:17,680
the default ones make a lot of sense.

112
00:08:17,980 --> 00:08:22,330
Makes a lot of sense that your email field should be connected to an email input widget.

113
00:08:22,570 --> 00:08:23,500
But of course, it's up to you.

114
00:08:23,510 --> 00:08:24,700
You have full control.

115
00:08:25,450 --> 00:08:33,190
So then the question came up on how to actually style just, for example, this text area widget.

116
00:08:33,370 --> 00:08:35,919
I don't want to actually add styling to the entire form.

117
00:08:36,460 --> 00:08:42,159
Well, the way you do that is inside the widget forms that text area.

118
00:08:42,700 --> 00:08:51,130
You can add in attributes or 8T, RSS and the attributes argument is itself a dictionary where you can

119
00:08:51,130 --> 00:08:55,540
begin to actually grab attributes that are common for each HTML.

120
00:08:55,840 --> 00:08:57,640
For example, the class call.

121
00:08:58,030 --> 00:09:02,980
So the way this would work, as you would say, OK, class and assign that to.

122
00:09:04,370 --> 00:09:10,160
My form, so note what I just did here, I basically said, OK, on this particular widget when you

123
00:09:10,160 --> 00:09:18,530
actually began rendering that into HTML, I want that widgets attribute to have the my form class upon

124
00:09:18,530 --> 00:09:19,010
rendering.

125
00:09:19,430 --> 00:09:21,740
Keep in mind, you have to do this inside the widget.

126
00:09:21,980 --> 00:09:24,830
You can't unfortunately do this inside the field itself.

127
00:09:24,860 --> 00:09:30,800
So if you want it to add in my form class for email, you would have to again assign widget is equal

128
00:09:30,800 --> 00:09:34,760
to forms that email widget and then set the attributes there.

129
00:09:35,570 --> 00:09:35,870
OK.

130
00:09:36,350 --> 00:09:42,620
So to show that this is working, I'm going to come back to Rentoul, review the HTML, and I'm going

131
00:09:42,620 --> 00:09:47,030
to get rid of my form on the container.

132
00:09:47,420 --> 00:09:56,480
So, no, now nowhere in the actual HTML file am I calling the my form class that was this custom border

133
00:09:56,480 --> 00:09:59,360
here that doesn't appear anywhere in the HTML.

134
00:09:59,750 --> 00:10:05,690
It only appears inside the attribute call inside of my widget inside my field.

135
00:10:06,290 --> 00:10:14,540
So when you save that and refresh your rental form, you should now see that CSS styling only occurring

136
00:10:14,750 --> 00:10:17,300
on that particular field or widget.

137
00:10:17,810 --> 00:10:25,550
So again, we now have that widget and we can directly see how it's going to be translated into an HTML.

138
00:10:25,580 --> 00:10:27,710
You can see why those attributes are there.

139
00:10:28,220 --> 00:10:33,530
And so then you can begin adding a lot more attributes that are directly related to any particular widget.

140
00:10:35,270 --> 00:10:40,940
For example, later on, you could look up what attributes are available for a text area tag, for example,

141
00:10:40,940 --> 00:10:47,420
you come to W3 school or any other resource like that and see, OK, I have attributes of like rows

142
00:10:47,420 --> 00:10:54,500
and columns I can pass in to make this square a different size than the default text area size here.

143
00:10:55,160 --> 00:10:56,140
So how do I do that?

144
00:10:56,150 --> 00:11:02,750
I would just come here to attributes, and I'm basically defining attributes on an HTML level, but

145
00:11:02,750 --> 00:11:05,570
inside Python, so I could say something like Rose.

146
00:11:06,110 --> 00:11:09,050
And let's have the speaker to use like two rows.

147
00:11:10,060 --> 00:11:14,290
And then let's say columns and have that be two columns.

148
00:11:14,620 --> 00:11:18,400
So, no, I'm just adding in more attributes into the attributes dictionary here.

149
00:11:19,090 --> 00:11:23,290
So save those changes, and those should probably be extreme enough that you would see the difference

150
00:11:23,290 --> 00:11:25,000
even if you're superhuman, like I am.

151
00:11:25,360 --> 00:11:28,030
I can see here it's only now default two by two.

152
00:11:28,600 --> 00:11:30,550
So notice now how much skinnier it is.

153
00:11:30,880 --> 00:11:35,710
OK, so pretty much all those attributes you can pass in to an HTML tag.

154
00:11:36,100 --> 00:11:41,920
So, for example, here I can see an HTML text area tag, which is from the text area widget, just

155
00:11:41,920 --> 00:11:43,350
to really zoom in here.

156
00:11:43,390 --> 00:11:50,740
I can see a bunch of attributes like ID or name or rows or columns or class, etc. All those things

157
00:11:50,740 --> 00:11:56,980
you can pass in as a dictionary, call inside as attributes and then give them whatever value you're

158
00:11:56,980 --> 00:11:57,550
interested in.

159
00:11:57,970 --> 00:11:59,890
And that is done through the widget.

160
00:11:59,950 --> 00:12:03,460
And then each field has a default widget they're connected to.

161
00:12:03,880 --> 00:12:10,000
And the one caveat being, you can't just pass in an attributes dictionary here in the fields.

162
00:12:10,000 --> 00:12:14,890
Unfortunately, you would need to actually manually call the widget reconnected, even if it's the same

163
00:12:14,890 --> 00:12:17,500
as the default widget and then pass the attributes.

164
00:12:17,800 --> 00:12:24,580
But that allows you to then do styling on the Python side of things and keep your HTML code clear.

165
00:12:24,790 --> 00:12:29,860
And we always want to try to keep these HTML forms as clean as possible because they can get really

166
00:12:29,860 --> 00:12:34,870
hard to read quite quickly versus Django tries to keep things a little more readable, especially if

167
00:12:34,870 --> 00:12:36,190
you're more comfortable.

168
00:12:36,190 --> 00:12:40,420
If Python that HTML, of course, depends on the person on where they want to do the styling.

169
00:12:40,750 --> 00:12:44,200
Technically, everything we did here could have been also done on HTML.

170
00:12:44,200 --> 00:12:46,780
Just would have been where you want to separate out the work.

171
00:12:47,710 --> 00:12:48,040
OK.

172
00:12:48,490 --> 00:12:49,660
That's it for this lecture.

173
00:12:49,690 --> 00:12:52,720
Coming up next, we're going to discuss using model forms.

174
00:12:53,020 --> 00:12:53,590
I'll see you there.

