1
00:00:05,430 --> 00:00:10,110
Welcome back, everyone, in this lecture, we're going to discuss the Django model form class.

2
00:00:11,660 --> 00:00:15,770
Now, often we're really using forms to directly interact with a model.

3
00:00:16,250 --> 00:00:21,470
We've already explored how to create a form that can just accept general information and then we can

4
00:00:21,470 --> 00:00:23,060
do whatever we want that information.

5
00:00:23,180 --> 00:00:28,760
But we're often using that to do things like create a new instance of a data point inside a model.

6
00:00:29,180 --> 00:00:34,940
This is common enough that fortunately, Django provides the model form class, which automatically

7
00:00:34,940 --> 00:00:38,390
creates a form with fields connected to each model field.

8
00:00:38,510 --> 00:00:45,200
And you can directly call things like save off of the form, which would save a new instance to your

9
00:00:45,200 --> 00:00:46,520
models in your database.

10
00:00:46,820 --> 00:00:48,140
Let's check this all out.

11
00:00:48,180 --> 00:00:52,370
Insider Code Editor OK, here I am inside Visual Studio Code.

12
00:00:52,700 --> 00:00:54,620
Here is our form.

13
00:00:54,620 --> 00:01:02,090
And technically speaking, when somebody submitted this form over in views that pie, we could do whatever

14
00:01:02,090 --> 00:01:04,910
we wanted with that information through the form.

15
00:01:04,910 --> 00:01:09,730
Not clean that data dictionary every time someone passed in an actual form.

16
00:01:09,740 --> 00:01:11,090
I've just been printing it out.

17
00:01:11,300 --> 00:01:16,460
But technically speaking, I could have done something like save that to a model that already existed

18
00:01:16,460 --> 00:01:17,360
on the back end.

19
00:01:17,810 --> 00:01:24,140
However, the reason I didn't really show that too much previously is because if we do plan on using

20
00:01:24,140 --> 00:01:30,800
forms with models, it makes a lot more sense to use Django's built in model form, a class that is

21
00:01:30,800 --> 00:01:35,690
going to automatically generate a form based off the fields inside a model.

22
00:01:35,900 --> 00:01:37,850
Now to do this, we first need a model.

23
00:01:38,270 --> 00:01:40,340
So we'll come back to explore.

24
00:01:41,450 --> 00:01:47,450
Open up models that pie inside the cars application, and let's create our first simple model.

25
00:01:48,450 --> 00:01:51,240
So we'll create a model called a review model.

26
00:01:52,210 --> 00:01:58,750
So same models thought model inheritance, and we'll just have this be a little simpler than before,

27
00:01:59,080 --> 00:02:05,560
we'll still accept the first name, so say models, a character field and let's say maxlength a 30.

28
00:02:06,340 --> 00:02:09,759
Let's also accept a last name for the person giving a review.

29
00:02:10,180 --> 00:02:15,690
So models again character field maxlength 30 and then just a change it up.

30
00:02:15,700 --> 00:02:21,070
Let's imagine this time we only want to accept stars like a star rating between one and five stars of

31
00:02:21,070 --> 00:02:22,060
their experience.

32
00:02:22,540 --> 00:02:24,730
So we'll create a attribute.

33
00:02:24,730 --> 00:02:29,470
Stars say models, and let's actually make this one an integer field.

34
00:02:31,100 --> 00:02:32,690
So we have our model.

35
00:02:32,930 --> 00:02:38,810
And what I also want to do is register this model inside my administration.

36
00:02:39,110 --> 00:02:40,310
So how do I do that?

37
00:02:40,640 --> 00:02:44,120
What I need to do is come to the admin that pi file.

38
00:02:44,540 --> 00:02:49,670
So I need to open this up and then open up admin that pie.

39
00:02:49,940 --> 00:02:51,380
And this is where we register a model.

40
00:02:51,390 --> 00:02:59,480
So I can say something like from that model's import, the review model we made and then register it

41
00:02:59,480 --> 00:03:01,790
with the admin or say, admin site.

42
00:03:02,950 --> 00:03:06,190
Register and then register the review model.

43
00:03:07,090 --> 00:03:12,760
OK, so I've created my model, but technically speaking, I haven't actually really registered it with

44
00:03:12,760 --> 00:03:16,630
the back end yet because I haven't run migrations for it, so I still need to do that.

45
00:03:17,110 --> 00:03:24,250
So I'm going to say python managed pie make migrations.

46
00:03:25,530 --> 00:03:32,040
And what looks like we have an indentation error inside models will come back here, and let's take

47
00:03:32,040 --> 00:03:33,140
care of that indentation.

48
00:03:33,140 --> 00:03:37,230
It looks like I had a little space there and everything is off by one space.

49
00:03:37,470 --> 00:03:38,730
My apologies there.

50
00:03:39,540 --> 00:03:41,190
OK, now let's save that.

51
00:03:42,060 --> 00:03:43,580
My background was too dark here.

52
00:03:43,590 --> 00:03:43,860
Really?

53
00:03:43,860 --> 00:03:44,610
Actually see that.

54
00:03:44,910 --> 00:03:45,810
So let's try it again.

55
00:03:46,020 --> 00:03:51,120
Python managed up pie make migrations perfect, so we initially created that review model.

56
00:03:51,420 --> 00:03:52,830
Now I'm just going to run the migration.

57
00:03:52,830 --> 00:03:56,370
So say Python managed pie migrate.

58
00:03:57,600 --> 00:03:58,110
Perfect.

59
00:03:58,410 --> 00:04:05,970
So now I should have a car on my actual back end in order to make sure it's actually working, let's

60
00:04:05,970 --> 00:04:10,290
create a super user so I can access the results from the admin page.

61
00:04:10,530 --> 00:04:15,840
So we'll say Python managed the pie, create super user.

62
00:04:17,200 --> 00:04:24,880
And the username, I was going to say, it's my admin email address will be my admin at Edmunds.com.

63
00:04:26,600 --> 00:04:28,610
Password will be my.

64
00:04:29,790 --> 00:04:31,680
Admin password.

65
00:04:32,220 --> 00:04:39,270
As we've mentioned before, it's technically invisible, so we'll enter their password again, my admin.

66
00:04:40,220 --> 00:04:42,050
Password, hopefully, you didn't mess that up.

67
00:04:42,350 --> 00:04:42,980
OK, perfect.

68
00:04:43,100 --> 00:04:48,650
Super user created successfully So now I have a way to actually check on the back end of the fact that

69
00:04:48,650 --> 00:04:51,440
it was registered there and we actually did some changes.

70
00:04:51,830 --> 00:04:54,260
So let's first confirm that that is working.

71
00:04:54,620 --> 00:05:02,630
So I'm going to go to my website and then visit the actual administration view and let's actually run.

72
00:05:02,630 --> 00:05:06,800
This will say Python managed up pie run server.

73
00:05:08,470 --> 00:05:10,630
OK, so our server is now running.

74
00:05:12,010 --> 00:05:20,320
I'm going to open up my Django admin view, so now I should be able to say my username, so my admin

75
00:05:20,860 --> 00:05:22,930
and then my admin.

76
00:05:24,010 --> 00:05:24,580
Password.

77
00:05:25,240 --> 00:05:30,760
I'm going to log in now and tonight I see groups, users, the default authentication authorization,

78
00:05:30,760 --> 00:05:33,610
but now I also see cars model so I can see reviews.

79
00:05:33,970 --> 00:05:40,330
And if I wanted to, I could add a manual review here first name, last name and then maybe give it

80
00:05:40,330 --> 00:05:40,950
some stars.

81
00:05:40,960 --> 00:05:42,640
So like one, two or five stars.

82
00:05:42,880 --> 00:05:45,130
Notice right now I can actually go above five stars.

83
00:05:45,280 --> 00:05:48,400
We're going to talk about errors and validation in the next lecture and customization.

84
00:05:48,760 --> 00:05:50,620
But for right now, I have, let's say, four stars.

85
00:05:50,920 --> 00:05:53,950
I can go ahead and save that, and I have my review object.

86
00:05:54,220 --> 00:05:54,550
OK.

87
00:05:55,000 --> 00:05:59,500
So obviously, I want the user to be able to provide that within a form.

88
00:06:00,040 --> 00:06:07,660
So what I could do is go through a very manual process of matching up a custom form here, making sure

89
00:06:07,660 --> 00:06:15,190
the fields match up and then later on inside of views that by having to make sure that I manually save

90
00:06:15,190 --> 00:06:21,940
form clean data by actually grabbing those things like, OK, grab the first name and then save that

91
00:06:21,940 --> 00:06:27,820
to the instance of a model, etc. But luckily for us, because this is so common, Django's already

92
00:06:27,820 --> 00:06:28,990
thought of something for us.

93
00:06:29,350 --> 00:06:33,130
So what this is called is a model form.

94
00:06:33,490 --> 00:06:34,210
How does this work?

95
00:06:34,330 --> 00:06:38,020
Well, I come back to the forms that file.

96
00:06:39,800 --> 00:06:45,440
So we'll come back to forms that PI file, and what I'm going to do right now is just comment all this

97
00:06:45,440 --> 00:06:45,870
out.

98
00:06:45,890 --> 00:06:48,560
So I'm going to basically not use that review form anymore.

99
00:06:49,010 --> 00:06:57,620
And instead, I'm going to say from that model's import, my model, which was the review model, then

100
00:06:57,620 --> 00:07:03,140
I'm also going to say from Let's make sure we don't do that on all caps from.

101
00:07:05,040 --> 00:07:08,440
Jane, go dot forms.

102
00:07:09,250 --> 00:07:10,740
Import the model form.

103
00:07:12,210 --> 00:07:19,200
OK, so this is essentially going to be like forms, but instead of that form, it's forms dot model

104
00:07:19,200 --> 00:07:22,890
form, but right now I'm just importing it like this so I can just pass in the model form.

105
00:07:23,310 --> 00:07:29,910
So let's show you how to essentially create a model form, which put simply looks at this model, looks

106
00:07:29,910 --> 00:07:34,830
at the fields and then will basically automatically generate something that looks like this, which

107
00:07:34,830 --> 00:07:37,650
automatically generates widgets, which automatically generates a form.

108
00:07:38,720 --> 00:07:41,420
So we're going to again say class.

109
00:07:41,810 --> 00:07:45,440
Let's keep the same name review form, so I don't need to worry about import changes later on.

110
00:07:45,950 --> 00:07:48,890
And now this is going to inherit from model form.

111
00:07:49,950 --> 00:07:55,080
And then all you need to do here is have a subclass called Meta.

112
00:07:55,380 --> 00:08:03,510
We say class meta where it has a single attribute for now and we say model is equal to review.

113
00:08:04,710 --> 00:08:10,140
And that's it, and it's kind of like magic, but really, we can kind of tell what it's doing, all

114
00:08:10,140 --> 00:08:12,240
it saying is, Hey, I have a model.

115
00:08:12,510 --> 00:08:14,310
Go ahead and make a form for it.

116
00:08:14,880 --> 00:08:19,710
So what I would encourage you to do at this point in time is also check out the documentation from this.

117
00:08:20,010 --> 00:08:26,100
So it's called creating forms from models, and it just talks about the model form and what we discussed

118
00:08:26,100 --> 00:08:26,400
here.

119
00:08:26,460 --> 00:08:27,790
Again, super easy.

120
00:08:27,790 --> 00:08:30,330
You just essentially connect it with model.

121
00:08:30,630 --> 00:08:35,610
And what you'll also notice is you can actually choose which fields should be represented inside the

122
00:08:35,640 --> 00:08:36,000
form.

123
00:08:36,480 --> 00:08:42,630
So if we come back here, we see that we have the attribute model, but maybe you don't actually want

124
00:08:42,630 --> 00:08:43,419
to collect everything.

125
00:08:43,440 --> 00:08:47,340
Maybe I only want to collect something like the first name or last name.

126
00:08:47,460 --> 00:08:51,510
So what I could do is come back to forms.

127
00:08:52,560 --> 00:08:59,070
So I come back to form that pie here and then say fields as my attribute and you just pass a list of

128
00:08:59,070 --> 00:09:04,830
the strings you want, such as first name and last name.

129
00:09:05,460 --> 00:09:12,570
Go ahead and save that change and remember review form that's still being imported over here and review

130
00:09:12,570 --> 00:09:12,870
form.

131
00:09:13,440 --> 00:09:20,730
And now I'm still just going to print out my form clean data, and I should be able to see things inside

132
00:09:20,730 --> 00:09:22,320
my actual rental.

133
00:09:22,440 --> 00:09:22,680
You.

134
00:09:24,640 --> 00:09:28,090
And you may have noticed we got a little air here, it says, oh, by the way, you forgot to actually

135
00:09:28,090 --> 00:09:30,570
create the fields attribute or exclude.

136
00:09:30,580 --> 00:09:32,590
So it's telling us, Hey, this needs updating.

137
00:09:32,920 --> 00:09:34,660
I'm going to refresh the page.

138
00:09:34,660 --> 00:09:37,180
I may need to restart the website if this didn't work.

139
00:09:37,690 --> 00:09:39,910
So, yeah, let's go ahead and hit control.

140
00:09:39,920 --> 00:09:42,640
See, that's one of those errors where you just have to rerun the website.

141
00:09:43,950 --> 00:09:44,320
There we go.

142
00:09:44,370 --> 00:09:45,540
Python managed up high.

143
00:09:45,570 --> 00:09:46,980
Go ahead and run that server again.

144
00:09:47,400 --> 00:09:54,550
And you should see now a very simple rental review form that only accepts a first name and a last name.

145
00:09:54,570 --> 00:09:57,480
And then if we hit submit query, we see, thank you.

146
00:09:57,960 --> 00:10:02,160
But notice over here we should see that actually printing out first name and last name.

147
00:10:02,730 --> 00:10:06,240
Now, obviously, we just connected this to a model.

148
00:10:06,660 --> 00:10:12,120
So what I could do is come back to forms and say, Hey, when somebody submits this form, actually

149
00:10:12,120 --> 00:10:14,790
want you to create a new instance of a review.

150
00:10:15,300 --> 00:10:17,430
Now for that, we should probably add in the stars.

151
00:10:18,060 --> 00:10:19,410
So we'll say first name.

152
00:10:19,410 --> 00:10:20,040
Last name.

153
00:10:21,260 --> 00:10:27,500
And add in stars save that, so now I should see all those fields inside my form.

154
00:10:27,860 --> 00:10:35,090
So if I come back here and refresh, I see first name, last name and stars, which is an integer field.

155
00:10:35,570 --> 00:10:39,070
Now, later on, we'll talk about errors and validations and that sort of thing.

156
00:10:39,080 --> 00:10:44,210
But for right now, I'm going to say first name, last name stars hit submit query and that should say

157
00:10:44,210 --> 00:10:44,690
thank you.

158
00:10:45,950 --> 00:10:47,540
And again, we see it printed out here.

159
00:10:47,570 --> 00:10:49,640
First name, last name stars.

160
00:10:50,730 --> 00:10:56,490
What you want to do now is save that as a new instance within your models, and then we can go ahead

161
00:10:56,490 --> 00:10:59,040
and go to admin to check that it's actually all working.

162
00:10:59,460 --> 00:11:01,490
And luckily for us, it's super easy.

163
00:11:01,500 --> 00:11:04,080
All we need to do is come back to views.

164
00:11:04,170 --> 00:11:09,480
And instead of saying something like print a firm, clean data, I just say OK, if that form is valid.

165
00:11:09,480 --> 00:11:13,490
For example, the length of the names weren't more than 30 characters.

166
00:11:13,500 --> 00:11:15,450
I simply say form.

167
00:11:16,720 --> 00:11:17,450
Not safe.

168
00:11:18,640 --> 00:11:25,000
And this single line, because it's a model form, is going to automatically save what the user passed

169
00:11:25,000 --> 00:11:27,280
in as a new instance of the model.

170
00:11:27,520 --> 00:11:28,210
Let's check it out.

171
00:11:28,810 --> 00:11:29,590
So we'll come back here.

172
00:11:30,550 --> 00:11:35,350
And remember, I'm still logged in here in my Django admin view with reviews and currently only have

173
00:11:35,350 --> 00:11:36,400
one review object.

174
00:11:36,880 --> 00:11:39,340
So we're going to come back to home here.

175
00:11:39,880 --> 00:11:42,940
And again, I'm going to refresh my rental review form.

176
00:11:43,300 --> 00:11:44,440
So let's give this a first name.

177
00:11:44,440 --> 00:11:47,020
The check, I'll say Jose Portela.

178
00:11:47,500 --> 00:11:49,300
Let's say I had a five star experience.

179
00:11:49,540 --> 00:11:50,980
I'll go ahead and submit the query.

180
00:11:51,850 --> 00:11:53,050
It says, thank you.

181
00:11:53,470 --> 00:11:56,380
And now if I come to the admin page, I'm going to go to reviews.

182
00:11:56,890 --> 00:11:59,830
No, I have a new review object and it's the one I just applied.

183
00:11:59,890 --> 00:12:02,260
Jose Portier five stars.

184
00:12:02,770 --> 00:12:03,400
Perfect.

185
00:12:03,820 --> 00:12:10,300
So look how easy it is now to let a user directly interact with creating new models.

186
00:12:10,750 --> 00:12:14,140
So we just need to say the model.

187
00:12:14,650 --> 00:12:20,380
Then we come to forms and call model form and then underneath class metta.

188
00:12:20,770 --> 00:12:25,810
You connect it with a model and you connect the fields in that model, you actually want to interact

189
00:12:25,810 --> 00:12:27,430
with and know how.

190
00:12:27,730 --> 00:12:34,030
This is why the original form had fields that looked a lot like the model fields like character field

191
00:12:34,030 --> 00:12:35,920
here was pretty much character field here.

192
00:12:36,340 --> 00:12:43,870
And what it does is it does a mapping of the model fields to the relevant form fields.

193
00:12:43,960 --> 00:12:49,780
And if you actually look up in the documentation the model forms, it actually gives you a table of

194
00:12:49,780 --> 00:12:50,890
what it maps to.

195
00:12:51,430 --> 00:12:57,460
So if we come back to the Django documentation creating forms for models, you'll see field types.

196
00:12:58,330 --> 00:13:02,770
Essentially, there are certain model fields that are represented as farm fields.

197
00:13:02,890 --> 00:13:08,830
So, for example, we can see character field for model field is represented by a character field for

198
00:13:09,010 --> 00:13:12,330
a form field, and you can see most of them are kind of one to one.

199
00:13:12,340 --> 00:13:15,250
There's date field eight field email field email field.

200
00:13:15,550 --> 00:13:21,790
Some don't actually have representation in the form like auto field or big auto field.

201
00:13:22,060 --> 00:13:26,050
Those are typically used for the primary key index, and that's not something you actually want to represent

202
00:13:26,050 --> 00:13:26,530
in the form.

203
00:13:26,800 --> 00:13:31,900
You don't want some user to be able to almost like hack into your database and rewrite primary keys.

204
00:13:32,140 --> 00:13:36,640
That's why you don't see auto field and big auto field as form fields.

205
00:13:36,790 --> 00:13:39,970
But here you can see the mapping of the model field and the form field.

206
00:13:40,060 --> 00:13:44,890
I should also mention there's a ton more information here on again specifying which widgets to use.

207
00:13:45,190 --> 00:13:47,530
So a lot of it looks kind of similar.

208
00:13:47,590 --> 00:13:52,330
Again, you're saying widgets, then you say, OK, make this a text area, then make it the attributes,

209
00:13:52,330 --> 00:13:55,360
etc. There is a little more work you have to do.

210
00:13:55,390 --> 00:13:58,120
You have to use something called model forms that underscore factory.

211
00:13:58,480 --> 00:14:01,510
I'll go ahead and let you explore that documentation on your own.

212
00:14:01,870 --> 00:14:03,180
It's not so bad.

213
00:14:03,190 --> 00:14:07,300
You basically just come here and create a new model form set.

214
00:14:07,450 --> 00:14:11,620
Again, it's more and more customization, depending on what you want to do here, for which widgets

215
00:14:11,950 --> 00:14:13,840
in general we're trying to save ourselves work.

216
00:14:13,840 --> 00:14:20,110
So often the default choices are good enough for us, but that was the way you could automatically connect

217
00:14:20,440 --> 00:14:25,720
a model form with a model in the backend, and we just saw that work together.

218
00:14:26,170 --> 00:14:30,940
Now I want you to keep in mind when we learn about class based views, that's going to give us even

219
00:14:30,940 --> 00:14:37,510
more power to automatically render an entire web page that specific for creating, reading, updating

220
00:14:37,510 --> 00:14:39,460
and deleting items from a model.

221
00:14:39,790 --> 00:14:42,610
So don't think we've kind of reached the pinnacle of Django yet?

222
00:14:42,880 --> 00:14:49,280
It gets even better kind of all building off of this idea of model forms and the idea that we often

223
00:14:49,300 --> 00:14:52,930
track website for form on the front end and a model on the back end.

224
00:14:53,350 --> 00:14:57,880
Coming up next, what I want to talk about are a bunch of other attributes that are going to be useful

225
00:14:58,090 --> 00:15:00,830
in customizing our model forms.

226
00:15:00,850 --> 00:15:06,160
But again, I want to make it clear when we're talking about things like how do I use a model form to

227
00:15:06,160 --> 00:15:09,220
maybe delete an instance for a model or update an instance for a model?

228
00:15:09,520 --> 00:15:11,710
Well, you can't technically do that with a model form.

229
00:15:11,980 --> 00:15:16,240
I would highly encourage you to wait until you learn about class based views before you head down that

230
00:15:16,240 --> 00:15:21,280
direction, because class-based views in the next section are going to make that even easier than using

231
00:15:21,290 --> 00:15:21,880
model forms.

232
00:15:22,120 --> 00:15:26,320
So trust me, it gets even better than this, even though this is already pretty darn good.

233
00:15:26,800 --> 00:15:30,430
So I'll see you in the next lecture when we talk about customizing model forms.

