在保存所有表单实例的引用时,django中的内存泄漏 [英] Memory leak in django when keeping a reference of all instances of forms

查看:108
本文介绍了在保存所有表单实例的引用时,django中的内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是追踪这个线程

我已经实现了在数组中保留对我所有表单的引用的方法像在这个选择的答案中提到的,但不幸的是,我在每个向django主机的请求中收到内存泄漏。

I have implemented the method for keeping a reference to all my forms in a array like mentioned by the selected answer in this but unfortunately I am getting a memory leak on each request to the django host.

有关代码如下:

这是我的扩展的自定义形式,它具有一个保持邻接表单引用的功能,每当我实例化一个新的表单时,它只会继续添加到_instances堆栈中。 / p>

This is my custom form I am extending which has a function to keep reference of neighboring forms, and whenever I instantiate a new form, it just keeps getting added to the _instances stack.

class StepForm(ModelForm):
    TAGS = []
    _instances = []

    def __new__(cls, *args, **kwargs):
        instance = object.__new__(cls)
        cls._instances.append(instance)
        return instance

即使这更像一个python问题,然后Django我决定最好向您展示我遇到这个问题的完整上下文。

Even though this more of a python issue then Django I have decided that it's better to show you the full context that I am encountering this problem at.

根据要求,我发布了我想通过这个壮举完成的任务:

As requested I am posting what I am trying to accomplish with this feat:

我有一个js小程序,有步骤,每一步都有一个表单,但是为了通过JS动态地加载每个步骤的内容,我需要在下一个表单中执行一些调用。和以前一样因此,我可以想出的唯一解决方案是只要保留对每个请求的所有表单的引用,并使用我需要的表单函数。

I have a js applet with steps, and for each step there is a form, but in order to load the contents of each step dynamically through JS I need to execute some calls on the next form in line. And on the previous aswell. Therefore the only solution I Could come up with is to just keep a reference to all forms on each request and just use the forms functions I need.

推荐答案

这不仅是一个Python问题 - 执行上下文(这里是Django应用程序)也很重要。正如Ludwik Trammer正确评论的那样,您处于长时间的过程中,因此模块或类级别的任何内容都将在该过程的持续时间内生活。此外,如果使用多个流程来提供应用程序,您可能会(并将会)从一个请求中获取不一致的结果,因为来自同一用户的两个后续请求可以(并且将最终由不同进程提供)。

Well it's not only a Python issue - the execution context (here a Django app) is important too. As Ludwik Trammer rightly comments, you're in a long running process, and as such anything at the module or class level will live for the duration of the process. Also if using more than one process to serve the app you may (and will) get inconsistant results from one request to another, since two subsequent requests from a same user can (and will) end up being served by different processes.

为了简短说明:在Web应用程序中安全保持每用户持久状态的方法是使用会话。请说明您正在尝试解决的问题,可能是一个更适合(可能是现有和测试的)解决方案。

To make a long story short: the way to safely keep per-user persistant state in a web application is to use sessions. Please explain what problem you're trying to solve, there's very probably a more appropriate (and possibly existing and tested) solution.

编辑:是一个向导。 Django有几个可用的实现,但大多数都不会处理回来 - 从经验来看,每个步骤都取决于前一个步骤(这是使用向导的驱动点之一)可能会变得棘手。通常做的是具有一组向导类(简单的老Python对象)。

EDIT : ok what you're looking for is a "wizard". There are a couple available implementations for Django but most of them don't handle going back - which, from experience, can get tricky when each step depends on the previous one (and that's one of the driving points for using a wizard). What one usually do is have a `Wizard' class (plain old Python object) with a set of forms.

向导照顾


  1. 步骤导航

  2. instanciating表单

  3. 维护状态(其中包括存储和检索每个步骤的表单数据,重新验证等)。

FWIW使用Django现有的基于会话的向导,我已经取得了很大的成功。我们为另一个项目(以某种复杂的要求)滚动了自己的工作,而它的工作,我不会命名它成功。在混合中投放ajax和文件上传也不会有帮助。无论如何,您可以尝试从现有的实现开始,查看它是否符合您的需求,如果没有,那么可以使用自定义解决方案 - 通用解决方案有时会使事情变得更困难。

FWIW I've had rather mixed success using Django's existing session-based wizard. We rolled our own for another project (with somehow complex requirements) and while it works I wouldn't name it a success neither. Having ajax and file uploads thrown in the mix doesn't help neither. Anyway, you can try to start with an existing implementation, see how it fits your needs, and go for a custom solution if it doesn't - generic solutions sometimes make things harder than they have to be.

我的2美分...

这篇关于在保存所有表单实例的引用时,django中的内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆