我无法在基于类的视图中在方法之间传递数值。

huangapple go评论67阅读模式
英文:

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

我建议以下操作:

  1. 将大部分的 post() 方法移到 form_valid() 方法中。在你的 post() 方法内创建 if form.is_valid() 语句没有意义,因为这个逻辑恰好是类视图中 postform_valid 之间的默认步骤。
  2. 移除整个 __init__() 方法,直接将 messagebundle 字典传递给 get_context() 方法。
  3. 移除对 TemplateView 的继承。因为你明显想要在最后显示一个模板,FormView 已经将模板处理混入其中。
  4. 你可能还想移除 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:

  1. Move most of your 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.
  2. Remove the entire __init__() method and pass message and bundle dicts directly to the get_context() method
  3. 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.
  4. You might also want to remove the 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.

huangapple
  • 本文由 发表于 2023年6月5日 20:31:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76406440.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定