@@ -32,6 +32,28 @@ def test_add_another(self):
32
32
self .assertEqual (review .title , "Not so great" )
33
33
self .assertEqual (review .rating , 1 )
34
34
35
+ def test_no_change (self ):
36
+ movie = Movie .objects .create (
37
+ title = "Lion King" ,
38
+ reviews = [Review (title = "Great!" , rating = 10 )],
39
+ )
40
+ data = {
41
+ "title" : "Lion King" ,
42
+ "reviews-0-title" : "Great!" ,
43
+ "reviews-0-rating" : "10" ,
44
+ "reviews-TOTAL_FORMS" : 2 ,
45
+ "reviews-INITIAL_FORMS" : 1 ,
46
+ }
47
+ form = MovieForm (data , instance = movie )
48
+ self .assertTrue (form .is_valid ())
49
+ form .save ()
50
+ self .assertEqual (form .changed_data , [])
51
+ movie .refresh_from_db ()
52
+ self .assertEqual (len (movie .reviews ), 1 )
53
+ review = movie .reviews [0 ]
54
+ self .assertEqual (review .title , "Great!" )
55
+ self .assertEqual (review .rating , 10 )
56
+
35
57
def test_update (self ):
36
58
movie = Movie .objects .create (
37
59
title = "Lion King" ,
@@ -47,6 +69,7 @@ def test_update(self):
47
69
form = MovieForm (data , instance = movie )
48
70
self .assertTrue (form .is_valid ())
49
71
form .save ()
72
+ self .assertEqual (form .changed_data , ["reviews" ])
50
73
movie .refresh_from_db ()
51
74
self .assertEqual (len (movie .reviews ), 1 )
52
75
review = movie .reviews [0 ]
@@ -149,34 +172,38 @@ def test_delete_required(self):
149
172
self .assertFalse (form .is_valid ())
150
173
self .assertEqual (form .errors ["reviews" ], ["This field cannot be blank." ])
151
174
152
- # def test_nullable_field(self):
153
- # """A nullable EmbeddedModelField is removed if all fields are empty ."""
154
- # author = Author .objects.create(
155
- # name="Bob ",
156
- # age=50 ,
157
- # address=Address(city="NYC ", state="NY", zip_code="10001") ,
158
- # billing_address=Address(city="NYC", state="NY", zip_code="10001"),
159
- # )
160
- # data = {
161
- # "name ": "Bob ",
162
- # "age ": 51 ,
163
- # "address-po_box ": "",
164
- # "address-city ": "New York City" ,
165
- # "address-state ": "NY" ,
166
- # "address-zip_code ": "10001 ",
167
- # "billing_address-po_box ": "",
168
- # "billing_address-city ": "",
169
- # "billing_address-state ": "" ,
170
- # "billing_address-zip_code ": "" ,
171
- # }
172
- # form = AuthorForm (data, instance=author )
173
- # self.assertTrue(form.is_valid())
174
- # form.save()
175
- # author .refresh_from_db()
176
- # self.assertIsNone(author.billing_address )
175
+ def test_nullable_field (self ):
176
+ """A nullable field is emptied if all rows are deleted ."""
177
+ movie = Movie .objects .create (
178
+ title = "Lion King " ,
179
+ reviews = [ Review ( title = "Great!" , rating = 10 )] ,
180
+ featured_reviews = [ Review ( title = "Okay " , rating = 5 )] ,
181
+ )
182
+ data = {
183
+ "title" : "Lion King" ,
184
+ "reviews-0-title " : "Not so great " ,
185
+ "reviews-0-rating " : "1" ,
186
+ "reviews-0-DELETE " : "" ,
187
+ "reviews-TOTAL_FORMS " : 2 ,
188
+ "reviews-INITIAL_FORMS " : 1 ,
189
+ "featured-reviews-0-title " : "Okay " ,
190
+ "featured-reviews-0-rating " : "5 " ,
191
+ "featured-reviews-0-DELETE " : "1 " ,
192
+ "featured-reviews-TOTAL_FORMS " : 2 ,
193
+ "featured-reviews-INITIAL_FORMS " : 1 ,
194
+ }
195
+ form = MovieForm (data , instance = movie )
196
+ self .assertTrue (form .is_valid ())
197
+ form .save ()
198
+ movie .refresh_from_db ()
199
+ self .assertEqual ( len ( movie . featured_reviews ), 0 )
177
200
178
201
def test_rendering (self ):
179
202
form = MovieForm ()
203
+ self .assertHTMLEqual (
204
+ str (form .fields ["reviews" ].get_bound_field (form , "reviews" ).label_tag ()),
205
+ '<label for="id_reviews">Reviews:</label>' ,
206
+ )
180
207
self .assertHTMLEqual (
181
208
str (form .fields ["reviews" ].get_bound_field (form , "reviews" )),
182
209
"""
@@ -209,6 +236,64 @@ def test_rendering(self):
209
236
name="reviews-MAX_NUM_FORMS" value="1000" id="id_reviews-MAX_NUM_FORMS">""" ,
210
237
)
211
238
239
+ def test_rendering_initial (self ):
240
+ movie = Movie .objects .create (
241
+ title = "Lion King" ,
242
+ reviews = [Review (title = "Great!" , rating = 10 )],
243
+ )
244
+ form = MovieForm (instance = movie )
245
+ self .assertHTMLEqual (
246
+ str (form .fields ["reviews" ].get_bound_field (form , "reviews" )),
247
+ """
248
+ <table>
249
+ <tbody><tr>
250
+ <th><label for="id_reviews-0-title">Title:</label></th>
251
+ <td>
252
+ <input type="text" name="reviews-0-title" maxlength="255"
253
+ id="id_reviews-0-title" value="Great!">
254
+ </td>
255
+ </tr>
256
+ <tr>
257
+ <th><label for="id_reviews-0-rating">Rating:</label></th>
258
+ <td>
259
+ <input type="number" name="reviews-0-rating"
260
+ id="id_reviews-0-rating" value="10">
261
+ </td>
262
+ </tr>
263
+ <tr>
264
+ <th><label for="id_reviews-0-DELETE">Delete:</label></th>
265
+ <td>
266
+ <input type="checkbox" name="reviews-0-DELETE" id="id_reviews-0-DELETE">
267
+ </td>
268
+ </tr></tbody>
269
+ <tbody><tr>
270
+ <th><label for="id_reviews-1-title">Title:</label></th>
271
+ <td>
272
+ <input type="text" name="reviews-1-title" maxlength="255" id="id_reviews-1-title">
273
+ </td>
274
+ </tr>
275
+ <tr>
276
+ <th><label for="id_reviews-1-rating">Rating:</label></th>
277
+ <td>
278
+ <input type="number" name="reviews-1-rating" id="id_reviews-1-rating">
279
+ </td>
280
+ </tr>
281
+ <tr>
282
+ <th><label for="id_reviews-1-DELETE">Delete:</label></th>
283
+ <td>
284
+ <input type="checkbox" name="reviews-1-DELETE" id="id_reviews-1-DELETE">
285
+ </td>
286
+ </tr></tbody>
287
+ </table>
288
+ <input type="hidden" name="reviews-TOTAL_FORMS" value="2"
289
+ id="id_reviews-TOTAL_FORMS"><input type="hidden"
290
+ name="reviews-INITIAL_FORMS" value="1"
291
+ id="id_reviews-INITIAL_FORMS">
292
+ <input type="hidden" name="reviews-MIN_NUM_FORMS" value="0"
293
+ id="id_reviews-MIN_NUM_FORMS"><input type="hidden"
294
+ name="reviews-MAX_NUM_FORMS" value="1000" id="id_reviews-MAX_NUM_FORMS">""" ,
295
+ )
296
+
212
297
213
298
# class NestedFormTests(TestCase):
214
299
# def test_update(self):
0 commit comments