英文:
I cannot pass the values between the methods in classBasedView
问题
我需要将bundle和message的值传递给get_context_data()方法,但我无法弄清楚如何做到这一点。
在这个实例中,当我传递它时,表单是有效的(当我弄清楚为什么数据在post方法中更新,但在get_context_data()中不更新时,我可以添加更好的错误处理)。
表单只有一个字段,它接受文件。
请帮忙。
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 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)
答案1
得分: 1
我建议以下操作:
- 将大部分的
post()
方法移到form_valid()
方法中。在你的post()
方法内创建if form.is_valid()
语句没有意义,因为这个逻辑恰好是类视图中post
和form_valid
之间的默认步骤。 - 移除整个
__init__()
方法,直接将message
和bundle
字典传递给get_context()
方法。 - 移除对
TemplateView
的继承。因为你明显想要在最后显示一个模板,FormView
已经将模板处理混入其中。 - 你可能还想移除
if isinstance(form, forms.InitialFirmwareForm2)
... 我的意思是,你通过form_class = ...
定义了此视图的表单。那么为什么要怀疑它会接受正确的表单?
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):
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): # 为什么要这样?
if self.request.FILES:
if "file" in self.request.FILES:
file = self.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": "表单成功解析"
})
except Exception as e:
print("出现错误", e)
else:
print("request.FILES 中没有文件 - 此情况未处理。")
else:
print("request.FILES 不为真值。")
return render(self.request, self.template_name, context=self.get_context_data(message=message, bundle=bundle))
当然,你需要删除这些打印语句。但它们提示了你的代码目前未处理的情况。如果这对你有帮助,请告诉我。
英文:
I'd recommend the following:
- Move most of your
post()
method toform_valid()
method. It does not make sense to create theif form.is_valid()
statement inside of yourpost()
because exactly that logic is the default step betweenpost
andform_valid
in class-based-views. - Remove the entire
__init__()
method and passmessage
andbundle
dicts directly to theget_context()
method - Remove the inheritance of
TemplateView
.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. - You might also want to remove the
if isinstance(form, forms.InitialFirmwareForm2)
... I mean you are defining the form for this view viaform_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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论