I need to pass the bundle and the message values to get_context_data() method, but I cannot figure out how to do it. In this instance the form is valid when I pass it (I can add the better error handling when I figure out why the data gets updated in the post method, but doesn't in the get_context_data()). The form has just 1 filed and it takes the file.
Please help.
class FirmwareView(FormView, TemplateView):
template_name = "dev_tools/firmware_cbv2.html"
form_class = forms.InitialFirmwareForm2
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.bundle = {}
self.message = {}
def get_success_url(self):
return self.request.path
def post(self, request, *args, **kwargs):
form = self.get_form()
if form.is_valid():
if request.FILES:
if "file" in request.FILES:
file = request.FILES["file"]
try:
content = json.loads(file.read().decode('utf-8'))
folder_name = utils.format_folder_name(content["title"])
units = []
for unit in content["units"]:
units.append(unit)
self.bundle["units"] = units
self.bundle["file"] = {
"name": folder_name,
"content": json.dumps(content)
}
self.message = {
"type": "info",
"content": "The form was parsed successfully"
}
except Exception as e:
print("there was an error", e)
return self.form_valid(form)
else:
print("the form is invalid")
return self.form_invalid(form)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["bundle"] = self.bundle
context["msg"] = self.message
return context
def form_valid(self, form):
if isinstance(form, forms.InitialFirmwareForm2):
return super().form_valid(form)
I'd recommend the following:
post()
method to form_valid()
method. It does not make sense to create the if form.is_valid()
statement inside of your post()
because exactly that logic is the default step between post
and form_valid
in class-based-views.__init__()
method and pass message
and bundle
dicts directly to the get_context()
methodTemplateView
. FormView
already has the template handling mixed in as a mixin because it is obvious that you want to show a template in the end.if isinstance(form, forms.InitialFirmwareForm2)
... I mean you are defining the form for this view via form_class = ...
. So why are you doubting it takes the correct form?class FirmwareView(FormView, TemplateView):
template_name = "dev_tools/firmware_cbv2.html"
form_class = forms.InitialFirmwareForm2
def get_success_url(self):
return self.request.path
def form_invalid(self, form):
print("the form is invalid")
return super().form_invalid(form)
def get_context_data(self, message=None, bundle=None,**kwargs):
context = super().get_context_data(**kwargs)
context['bundle'] = bundle
context['message'] = message
return context
def form_valid(self, form):
bundle, message = {}, {}
if isinstance(form, forms.InitialFirmwareForm2): # why this?
if request.FILES:
if "file" in request.FILES:
file = request.FILES["file"]
try:
content = json.loads(file.read().decode('utf-8'))
folder_name = utils.format_folder_name(content["title"])
units = []
for unit in content["units"]:
units.append(unit)
bundle["units"] = units
bundle["file"] = {
"name": folder_name,
"content": json.dumps(content)
}
message.update({
"type": "info",
"content": "The form was parsed successfully"
})
except Exception as e:
print("there was an error", e)
else:
print("No files in request.FILES - this situation is not handled.")
else:
print("request.FILES does not evaluate to True")
return render(self.request, self.template_name, context=self.get_context_data(message=message, bundle=bundle))
Of course you have to get rid of the print statements. But they hint you to situations that are not covered by your code right now.
Let me know if this works out for you.