|
|
@@ -171,6 +171,13 @@ class ProductCreateUpdateView(generic.UpdateView):
|
|
171
|
171
|
recommendations_formset = ProductRecommendationFormSet
|
|
172
|
172
|
stockrecord_formset = StockRecordFormSet
|
|
173
|
173
|
|
|
|
174
|
+ def __init__(self, *args, **kwargs):
|
|
|
175
|
+ super(ProductCreateUpdateView, self).__init__(*args, **kwargs)
|
|
|
176
|
+ self.formsets = {'category_formset': self.category_formset,
|
|
|
177
|
+ 'image_formset': self.image_formset,
|
|
|
178
|
+ 'recommended_formset': self.recommendations_formset,
|
|
|
179
|
+ 'stockrecord_formset': self.stockrecord_formset}
|
|
|
180
|
+
|
|
174
|
181
|
def get_queryset(self):
|
|
175
|
182
|
"""
|
|
176
|
183
|
Filter products that the user doesn't have permission to update
|
|
|
@@ -202,17 +209,13 @@ class ProductCreateUpdateView(generic.UpdateView):
|
|
202
|
209
|
def get_context_data(self, **kwargs):
|
|
203
|
210
|
ctx = super(ProductCreateUpdateView, self).get_context_data(**kwargs)
|
|
204
|
211
|
ctx['product_class'] = self.product_class
|
|
205
|
|
- if 'stockrecord_formset' not in ctx:
|
|
206
|
|
- ctx['stockrecord_formset'] = self.stockrecord_formset(
|
|
207
|
|
- self.product_class, self.request.user, instance=self.object)
|
|
208
|
|
- if 'category_formset' not in ctx:
|
|
209
|
|
- ctx['category_formset'] \
|
|
210
|
|
- = self.category_formset(instance=self.object)
|
|
211
|
|
- if 'image_formset' not in ctx:
|
|
212
|
|
- ctx['image_formset'] = self.image_formset(instance=self.object)
|
|
213
|
|
- if 'recommended_formset' not in ctx:
|
|
214
|
|
- ctx['recommended_formset'] \
|
|
215
|
|
- = self.recommendations_formset(instance=self.object)
|
|
|
212
|
+
|
|
|
213
|
+ for ctx_name, formset_class in self.formsets.iteritems():
|
|
|
214
|
+ if ctx_name not in ctx:
|
|
|
215
|
+ ctx[ctx_name] = formset_class(self.product_class,
|
|
|
216
|
+ self.request.user,
|
|
|
217
|
+ instance=self.object)
|
|
|
218
|
+
|
|
216
|
219
|
if self.object is None:
|
|
217
|
220
|
ctx['title'] = _('Create new %s product') % self.product_class.name
|
|
218
|
221
|
else:
|
|
|
@@ -224,12 +227,6 @@ class ProductCreateUpdateView(generic.UpdateView):
|
|
224
|
227
|
kwargs['product_class'] = self.product_class
|
|
225
|
228
|
return kwargs
|
|
226
|
229
|
|
|
227
|
|
- def form_valid(self, form):
|
|
228
|
|
- return self.process_all_forms(form)
|
|
229
|
|
-
|
|
230
|
|
- def form_invalid(self, form):
|
|
231
|
|
- return self.process_all_forms(form)
|
|
232
|
|
-
|
|
233
|
230
|
def process_all_forms(self, form):
|
|
234
|
231
|
"""
|
|
235
|
232
|
Short-circuits the regular logic to have one place to have our
|
|
|
@@ -240,39 +237,45 @@ class ProductCreateUpdateView(generic.UpdateView):
|
|
240
|
237
|
if self.creating and form.is_valid():
|
|
241
|
238
|
self.object = form.save()
|
|
242
|
239
|
|
|
243
|
|
- stockrecord_formset = self.stockrecord_formset(
|
|
244
|
|
- self.product_class, self.request.user,
|
|
245
|
|
- self.request.POST, instance=self.object)
|
|
246
|
|
- category_formset = self.category_formset(
|
|
247
|
|
- self.request.POST, instance=self.object)
|
|
248
|
|
- image_formset = self.image_formset(
|
|
249
|
|
- self.request.POST, self.request.FILES, instance=self.object)
|
|
250
|
|
- recommended_formset = self.recommendations_formset(
|
|
251
|
|
- self.request.POST, self.request.FILES, instance=self.object)
|
|
252
|
|
-
|
|
253
|
|
- is_valid = all([
|
|
254
|
|
- form.is_valid(),
|
|
255
|
|
- category_formset.is_valid(),
|
|
256
|
|
- image_formset.is_valid(),
|
|
257
|
|
- recommended_formset.is_valid(),
|
|
258
|
|
- stockrecord_formset.is_valid(),
|
|
259
|
|
- ])
|
|
260
|
|
-
|
|
261
|
|
- if is_valid:
|
|
262
|
|
- return self.forms_valid(
|
|
263
|
|
- form, stockrecord_formset, category_formset,
|
|
264
|
|
- image_formset, recommended_formset)
|
|
|
240
|
+ formsets = {}
|
|
|
241
|
+ for ctx_name, formset_class in self.formsets.iteritems():
|
|
|
242
|
+ formsets[ctx_name] = formset_class(self.product_class,
|
|
|
243
|
+ self.request.user,
|
|
|
244
|
+ self.request.POST,
|
|
|
245
|
+ self.request.FILES,
|
|
|
246
|
+ instance=self.object)
|
|
|
247
|
+
|
|
|
248
|
+ is_valid = form.is_valid() and all([formset.is_valid()
|
|
|
249
|
+ for formset in formsets.values()])
|
|
|
250
|
+
|
|
|
251
|
+ cross_form_validation_result = self.clean(form, formsets)
|
|
|
252
|
+ if is_valid and cross_form_validation_result:
|
|
|
253
|
+ return self.forms_valid(form, formsets)
|
|
265
|
254
|
else:
|
|
266
|
255
|
# delete the temporary product again
|
|
267
|
|
- if self.creating and form.is_valid():
|
|
|
256
|
+ if self.creating and self.object and self.object.pk is not None:
|
|
268
|
257
|
self.object.delete()
|
|
269
|
258
|
self.object = None
|
|
270
|
|
- return self.forms_invalid(
|
|
271
|
|
- form, stockrecord_formset, category_formset,
|
|
272
|
|
- image_formset, recommended_formset)
|
|
|
259
|
+ return self.forms_invalid(form, formsets)
|
|
|
260
|
+
|
|
|
261
|
+ # form_valid and form_invalid are called depending on the validation result
|
|
|
262
|
+ # of just the product form and redisplay the form respectively return a
|
|
|
263
|
+ # redirect to the success URL. In both cases we need to check our formsets
|
|
|
264
|
+ # as well, so both methods do the same. process_all_forms then calls
|
|
|
265
|
+ # forms_valid or forms_invalid respectively, which do the redisplay or
|
|
|
266
|
+ # redirect.
|
|
|
267
|
+ form_valid = form_invalid = process_all_forms
|
|
|
268
|
+
|
|
|
269
|
+ def clean(self, form, formsets):
|
|
|
270
|
+ """
|
|
|
271
|
+ Perform any cross-form/formset validation. If there are errors, attach
|
|
|
272
|
+ errors to a form or a form field so that they are displayed to the user
|
|
|
273
|
+ and return False. If everything is valid, return True. This method will
|
|
|
274
|
+ be called regardless of whether the individual forms are valid.
|
|
|
275
|
+ """
|
|
|
276
|
+ return True
|
|
273
|
277
|
|
|
274
|
|
- def forms_valid(self, form, stockrecord_formset, category_formset,
|
|
275
|
|
- image_formset, recommended_formset):
|
|
|
278
|
+ def forms_valid(self, form, formsets):
|
|
276
|
279
|
"""
|
|
277
|
280
|
Save all changes and display a success url.
|
|
278
|
281
|
"""
|
|
|
@@ -281,23 +284,16 @@ class ProductCreateUpdateView(generic.UpdateView):
|
|
281
|
284
|
self.object = form.save()
|
|
282
|
285
|
|
|
283
|
286
|
# Save formsets
|
|
284
|
|
- category_formset.save()
|
|
285
|
|
- image_formset.save()
|
|
286
|
|
- recommended_formset.save()
|
|
287
|
|
- stockrecord_formset.save()
|
|
|
287
|
+ for formset in formsets.values():
|
|
|
288
|
+ formset.save()
|
|
288
|
289
|
|
|
289
|
290
|
return HttpResponseRedirect(self.get_success_url())
|
|
290
|
291
|
|
|
291
|
|
- def forms_invalid(self, form, stockrecord_formset, category_formset,
|
|
292
|
|
- image_formset, recommended_formset):
|
|
|
292
|
+ def forms_invalid(self, form, formsets):
|
|
293
|
293
|
messages.error(self.request,
|
|
294
|
294
|
_("Your submitted data was not valid - please "
|
|
295
|
295
|
"correct the below errors"))
|
|
296
|
|
- ctx = self.get_context_data(form=form,
|
|
297
|
|
- stockrecord_formset=stockrecord_formset,
|
|
298
|
|
- category_formset=category_formset,
|
|
299
|
|
- image_formset=image_formset,
|
|
300
|
|
- recommended_formset=recommended_formset)
|
|
|
296
|
+ ctx = self.get_context_data(form=form, **formsets)
|
|
301
|
297
|
return self.render_to_response(ctx)
|
|
302
|
298
|
|
|
303
|
299
|
def get_url_with_querystring(self, url):
|