1
1

00:00:01,190  -->  00:00:02,060 line:15% 
<v Jose>Hi, and welcome back.</v>
2

2

00:00:02,060  -->  00:00:04,310 line:15% 
Another video in inheritance, and in this one
3

3

00:00:04,310  -->  00:00:06,360 line:15% 
we're going to be moving methods
4

4

00:00:06,360  -->  00:00:11,230
from our models into the model parent class.
5

5

00:00:11,230  -->  00:00:14,660
Everything that's duplicated between those two item
6

6

00:00:14,660  -->  00:00:17,650
and alert models can usually move to a parent class
7

7

00:00:17,650  -->  00:00:22,400
as long as we make it generic enough that it can be moved.
8

8

00:00:22,400  -->  00:00:25,080
In this video we're going to learn how to do that.
9

9

00:00:25,080  -->  00:00:27,300
So here's a method that is duplicated
10

10

00:00:27,300  -->  00:00:32,300
between the two models, and that is this all method.
11

11

00:00:32,770  -->  00:00:36,320
So, so far we have an all method inside the item model,
12

12

00:00:36,320  -->  00:00:39,720
and we also have an all method inside the alert model,
13

13

00:00:39,720  -->  00:00:41,640
and it does basically the same thing.
14

14

00:00:41,640  -->  00:00:43,540
It gets stuff from a database
15

15

00:00:43,540  -->  00:00:47,200
from the appropriate collection, and then it returns a list
16

16

00:00:47,200  -->  00:00:51,520
of objects of the type that is being called.
17

17

00:00:51,520  -->  00:00:53,290
So if you call it with the item class,
18

18

00:00:53,290  -->  00:00:54,793
it'll return item models.
19

19

00:00:56,069  -->  00:00:57,560
If you call it with the alert class,
20

20

00:00:57,560  -->  00:01:00,260
it will return alert models.
21

21

00:01:00,260  -->  00:01:02,930
We can move this to the parent class,
22

22

00:01:02,930  -->  00:01:07,930
and very important, at this point you wanna be using cls.
23

23

00:01:08,250  -->  00:01:13,250
If you do alert, and you move this to the model, of course,
24

24

00:01:15,093  -->  00:01:18,527
both item and alert are gonna return alert objects.
25

25

00:01:18,527  -->  00:01:20,933
I'm gonna come back to that in just a moment.
26

26

00:01:22,100  -->  00:01:26,310
First of all, let's copy that and go over to our model,
27

27

00:01:26,310  -->  00:01:29,823
and I'm going to put it down here.
28

28

00:01:31,870  -->  00:01:33,330
Couple of things that this is gonna do
29

29

00:01:33,330  -->  00:01:38,150
is it is going to use database and list,
30

30

00:01:38,150  -->  00:01:43,150
so we do have to do from typing import list,
31

31

00:01:43,280  -->  00:01:48,220
and from common database, import database.
32

32

00:01:48,220  -->  00:01:51,050
So we do have to add those imports in there,
33

33

00:01:51,050  -->  00:01:54,060
and then we have a small problem.
34

34

00:01:54,060  -->  00:01:58,020
We have the problem where this method
35

35

00:01:58,020  -->  00:02:01,460
is accessing the alerts collection,
36

36

00:02:01,460  -->  00:02:03,990
but we don't want it to access the alerts collection
37

37

00:02:03,990  -->  00:02:06,070
because ideally what we wanna do
38

38

00:02:06,070  -->  00:02:11,070
is if we call this method like so, item.all,
39

39

00:02:13,620  -->  00:02:18,370
then obviously we wanna get back a list of items.
40

40

00:02:18,370  -->  00:02:23,323
If we do alert.all, we wanna get back a list of alerts.
41

41

00:02:24,960  -->  00:02:26,893
So how are we gonna do that?
42

42

00:02:26,893  -->  00:02:29,790
Well, this is a class method.
43

43

00:02:29,790  -->  00:02:33,120
That means that when we call this method,
44

44

00:02:33,120  -->  00:02:37,380
we have access to things that are defined in the class.
45

45

00:02:37,380  -->  00:02:38,960
We don't have access to things
46

46

00:02:38,960  -->  00:02:42,570
that are defined in any particular object.
47

47

00:02:42,570  -->  00:02:47,173
So, for example, when we create an item object,
48

48

00:02:48,050  -->  00:02:51,570
we define the url, tag name, and query of that object,
49

49

00:02:51,570  -->  00:02:54,100
and then once we have the object,
50

50

00:02:54,100  -->  00:02:58,210
we can access the self.url property, self.tag_name property,
51

51

00:02:58,210  -->  00:03:02,513
and so on, including self.collection.
52

52

00:03:03,500  -->  00:03:07,270
So, instead of hard coding items here,
53

53

00:03:07,270  -->  00:03:10,740
we could do potentially something like self.collection
54

54

00:03:11,730  -->  00:03:16,420
if this method was an instance method, but it's not.
55

55

00:03:16,420  -->  00:03:19,170
It's a class method so we can't do this.
56

56

00:03:19,170  -->  00:03:21,400
What alternative do we have?
57

57

00:03:21,400  -->  00:03:26,400
Since collection is always the same in all item objects,
58

58

00:03:26,630  -->  00:03:31,110
essentially it's always items, we can move this collection
59

59

00:03:31,110  -->  00:03:33,320
so that it stops being an instance property,
60

60

00:03:33,320  -->  00:03:36,880
stops being self.something, and instead
61

61

00:03:36,880  -->  00:03:39,500
is defined at the class level.
62

62

00:03:39,500  -->  00:03:43,700
That way, all items will have the same property,
63

63

00:03:43,700  -->  00:03:47,030
and we no longer need to have self
64

64

00:03:47,030  -->  00:03:48,770
in order to use the property.
65

65

00:03:48,770  -->  00:03:49,623
As you can see, we can't use it here
66

66

00:03:49,623  -->  00:03:51,310
because we don't have self.
67

67

00:03:51,310  -->  00:03:52,840
We have a class method.
68

68

00:03:52,840  -->  00:03:55,800
We have cls which is the class.
69

69

00:03:55,800  -->  00:03:58,890
That means, if we put the collection here
70

70

00:03:59,830  -->  00:04:04,830
and we take it away from here, now we can do cls.collection.
71

71

00:04:09,540  -->  00:04:11,200
Similarly, in the alert model,
72

72

00:04:11,200  -->  00:04:15,470
we can put collection here as alerts.
73

73

00:04:15,470  -->  00:04:17,630
We can remove it from there,
74

74

00:04:17,630  -->  00:04:20,773
and here we can use cls.collection.
75

75

00:04:22,610  -->  00:04:26,250
Now, by doing this, by putting the collection
76

76

00:04:26,250  -->  00:04:29,380
at the top level of the class level, that means that we
77

77

00:04:29,380  -->  00:04:34,380
no longer have this dependent on the specific objects,
78

78

00:04:34,570  -->  00:04:37,330
so we could do the same here, cls.collection.
79

79

00:04:37,330  -->  00:04:42,330
Instead of doing cls(**alert), what we're gonna do is simply
80

80

00:04:44,350  -->  00:04:46,663
take this and make it a bit more generic.
81

81

00:04:54,830  -->  00:04:58,300
Now there's a small problem which is that PyCharm will tell
82

82

00:04:58,300  -->  00:05:03,300
you that cls.collection is not defined, and it's correct.
83

83

00:05:03,520  -->  00:05:06,920
The model class does not have a collection property
84

84

00:05:06,920  -->  00:05:08,930
defined in it, so this warning,
85

85

00:05:08,930  -->  00:05:11,000
it tells you that it's not there.
86

86

00:05:11,000  -->  00:05:15,860
However, the subclasses do have a collection property.
87

87

00:05:15,860  -->  00:05:17,943
That's the power of cls.
88

88

00:05:18,860  -->  00:05:21,280
The subclass can have different properties
89

89

00:05:21,280  -->  00:05:24,320
from the parent class, and using cls means
90

90

00:05:24,320  -->  00:05:28,660
that if you call item.all, really what you're going
91

91

00:05:28,660  -->  00:05:33,480
is you're going to item.all, and that is going
92

92

00:05:33,480  -->  00:05:37,083
to use item.collection which is defined.
93

93

00:05:38,150  -->  00:05:43,150
We are never going to call model.all just because
94

94

00:05:43,870  -->  00:05:46,610
it doesn't make sense in our application to do that.
95

95

00:05:46,610  -->  00:05:48,430
However, you're still going to get this warning,
96

96

00:05:48,430  -->  00:05:51,910
and you can call model.all if you want,
97

97

00:05:51,910  -->  00:05:55,570
and if you call model.all, you're gonna have a problem
98

98

00:05:55,570  -->  00:05:57,490
because there is no collection property,
99

99

00:05:57,490  -->  00:05:59,710
so you're going to have a problem there,
100

100

00:05:59,710  -->  00:06:04,710
and also you cannot create model objects.
101

101

00:06:05,170  -->  00:06:07,840
There are two problems with the model-object creation.
102

102

00:06:07,840  -->  00:06:11,070
The first one is that you don't have a constructor
103

103

00:06:11,070  -->  00:06:14,680
in your model, so even if you found some data
104

104

00:06:14,680  -->  00:06:16,370
from the database, you're not gonna be able
105

105

00:06:16,370  -->  00:06:19,260
to create the model because there is no constructor
106

106

00:06:19,260  -->  00:06:22,120
that can accept the data coming from the database.
107

107

00:06:22,120  -->  00:06:23,603
There's no init method.
108

108

00:06:24,800  -->  00:06:27,570
Second problem, even if there was an init method,
109

109

00:06:27,570  -->  00:06:29,750
you still wouldn't be able to create a model object
110

110

00:06:29,750  -->  00:06:31,930
because you have this abstract method here,
111

111

00:06:31,930  -->  00:06:35,730
and as you know from the last video, you can't create
112

112

00:06:35,730  -->  00:06:39,300
objects of classes that have abstract methods.
113

113

00:06:39,300  -->  00:06:43,353
So these are a few issues with this help
114

114

00:06:44,380  -->  00:06:47,810
that you're getting from PyCharm and abstract classes,
115

115

00:06:47,810  -->  00:06:49,530
and I haven't really found a good,
116

116

00:06:49,530  -->  00:06:52,690
simple-enough way of avoiding these problems.
117

117

00:06:52,690  -->  00:06:55,880
So what you can do is you can define a collection
118

118

00:06:57,420  -->  00:07:00,963
variable here, and that get rids of this error,
119

119

00:07:01,920  -->  00:07:05,670
and you can define a dunder init method if you want
120

120

00:07:05,670  -->  00:07:10,580
with unlimited argument and keyword arguments, and make it
121

121

00:07:10,580  -->  00:07:14,660
do nothing, and that gets rid of this other error.
122

122

00:07:14,660  -->  00:07:17,700
This I think is fine to do.
123

123

00:07:17,700  -->  00:07:21,260
It's not perfect because this code here
124

124

00:07:21,260  -->  00:07:24,430
is only there to get rid of the warnings.
125

125

00:07:24,430  -->  00:07:26,330
It's not there to do anything,
126

126

00:07:26,330  -->  00:07:28,250
and I'm not a big fan of that.
127

127

00:07:28,250  -->  00:07:29,860
However, as I said, I haven't found
128

128

00:07:29,860  -->  00:07:32,850
another easy way of fixing the issue.
129

129

00:07:32,850  -->  00:07:36,380
There is a way of defining an abstract property
130

130

00:07:36,380  -->  00:07:40,590
which means that the subclasses would need to define
131

131

00:07:40,590  -->  00:07:45,590
collection, but this base class does not define collection.
132

132

00:07:45,740  -->  00:07:47,880
There is a way to do that but it's a bit more complicated.
133

133

00:07:47,880  -->  00:07:49,230
We may look at it later on.
134

134

00:07:50,740  -->  00:07:54,000
And there is no real way around the init method
135

135

00:07:54,000  -->  00:07:56,030
and this warning that you were getting here.
136

136

00:07:56,030  -->  00:07:58,030
So for now we're going to leave it as this.
137

137

00:07:58,030  -->  00:08:01,610
Later on, we're going to look at an improvement on it.
138

138

00:08:01,610  -->  00:08:03,950
Just remember that you're never going to be able
139

139

00:08:03,950  -->  00:08:07,040
to create objects of class model,
140

140

00:08:07,040  -->  00:08:09,500
so this code here is sort of superfluous.
141

141

00:08:09,500  -->  00:08:11,640
It's not really necessary other than
142

142

00:08:13,895  -->  00:08:16,160
to avoid the warnings, and the reason you wanna avoid
143

143

00:08:16,160  -->  00:08:19,590
the warnings, by the way, is because if you have a code
144

144

00:08:19,590  -->  00:08:21,760
that's full of warnings, you're probably not gonna
145

145

00:08:21,760  -->  00:08:24,000
pay attention to them just because you're gonna be like,
146

146

00:08:24,000  -->  00:08:26,370
oh yeah, there's another warning, whatever,
147

147

00:08:26,370  -->  00:08:28,790
and not paying attention to warnings can be a little bit
148

148

00:08:28,790  -->  00:08:31,460
dangerous 'cause often the warnings are helpful,
149

149

00:08:31,460  -->  00:08:33,260
so that's why I'm adding this here
150

150

00:08:33,260  -->  00:08:34,730
even though I'm not a big fan of it.
151

151

00:08:34,730  -->  00:08:37,070
I'm adding it there to avoid the warnings
152

152

00:08:37,070  -->  00:08:40,020
that I know I can get rid of without a problem
153

153

00:08:40,020  -->  00:08:42,210
so that if I do get any other warnings,
154

154

00:08:42,210  -->  00:08:43,780
I will pay attention to them because they will
155

155

00:08:43,780  -->  00:08:45,840
be the only warnings that are there.
156

156

00:08:45,840  -->  00:08:48,060
If I allow this to build up warnings,
157

157

00:08:48,060  -->  00:08:50,870
I'm eventually just not gonna care about them.
158

158

00:08:50,870  -->  00:08:52,740
That's known as the broken windows problem.
159

159

00:08:52,740  -->  00:08:54,180
If you're not familiar with it,
160

160

00:08:54,180  -->  00:08:56,513
something you wanna avoid in your code.
161

161

00:08:57,460  -->  00:08:59,080
All right, that's everything for this video.
162

162

00:08:59,080  -->  00:09:01,260
I just wanted to move the all method
163

163

00:09:01,260  -->  00:09:04,410
to teach you how you can think of this move
164

164

00:09:04,410  -->  00:09:07,350
from individual models into a base class,
165

165

00:09:07,350  -->  00:09:09,670
and of course we can go down here
166

166

00:09:09,670  -->  00:09:13,350
to our models and delete the all method.
167

167

00:09:13,350  -->  00:09:17,200
Now, what this is doing is, when you delete it,
168

168

00:09:17,200  -->  00:09:18,790
it's just doing exactly the same thing.
169

169

00:09:18,790  -->  00:09:21,320
Just think of it as a copy and paste
170

170

00:09:21,320  -->  00:09:23,370
because we're using cls.
171

171

00:09:23,370  -->  00:09:24,400
Because we're using cls,
172

172

00:09:24,400  -->  00:09:25,620
it's essentially a copy and paste.
173

173

00:09:25,620  -->  00:09:27,620
When you call it in the alert model,
174

174

00:09:27,620  -->  00:09:29,500
you're using alert.collection,
175

175

00:09:29,500  -->  00:09:31,810
and you're using the alert constructor.
176

176

00:09:31,810  -->  00:09:33,220
If you call it from the item model,
177

177

00:09:33,220  -->  00:09:36,100
you're using item.collection and the item constructor
178

178

00:09:36,100  -->  00:09:39,453
so it'll work in exactly the same way as it does here.
179

179

00:09:40,420  -->  00:09:43,410
Now, something else that you wanna
180

180

00:09:43,410  -->  00:09:45,790
think about is this init method.
181

181

00:09:45,790  -->  00:09:48,580
It says the call to the superclass is missed,
182

182

00:09:48,580  -->  00:09:53,270
so if you want to call the superclass, just do this.
183

183

00:09:53,270  -->  00:09:54,370
What does this do?
184

184

00:09:54,370  -->  00:09:57,760
Well, it goes over to the model class
185

185

00:09:57,760  -->  00:09:59,990
and calls the init method.
186

186

00:09:59,990  -->  00:10:02,780
This is something that Python expects you to do
187

187

00:10:02,780  -->  00:10:07,690
just so you don't miss anything in the chain of inheritance,
188

188

00:10:07,690  -->  00:10:09,104
and in this case, doing this does nothing
189

189

00:10:09,104  -->  00:10:10,533
for us but you still have to do it.
190

190

00:10:10,533  -->  00:10:13,360
This is one more reason why I'm not a big fan
191

191

00:10:13,360  -->  00:10:16,010
of that solution but for now, again, we're gonna put
192

192

00:10:16,010  -->  00:10:19,060
it there just because we do have a parent class,
193

193

00:10:19,060  -->  00:10:21,750
and we do want to call the init method
194

194

00:10:21,750  -->  00:10:24,710
in case we do add something here later on.
195

195

00:10:24,710  -->  00:10:25,890
We don't miss that later
196

196

00:10:25,890  -->  00:10:27,640
so we're gonna put it there for now.
197

197

00:10:27,640  -->  00:10:30,433
Later on, if we make changes, we can change that.
198

198

00:10:31,370  -->  00:10:33,030
Do note that you can put things
199

199

00:10:33,030  -->  00:10:34,500
in the init method if you want it.
200

200

00:10:34,500  -->  00:10:36,040
There's something that you want to share
201

201

00:10:36,040  -->  00:10:38,880
across all objects, all your models, then you can put
202

202

00:10:38,880  -->  00:10:41,130
it there and that's totally fine thing to do.
203

203

00:10:42,010  -->  00:10:44,090
All right, thanks for joining me in this video.
204

204

00:10:44,090  -->  00:10:45,540
I'll see you on the next one.
