在Django中,当使用admin.StackedInline时,如何线程安全地将请求传递给表单'__init__?

时间:2013-02-26 10:37:37

标签: python django thread-safety django-admin

我想在StackedInline的formset中将请求传递给我的表单。现在我有:

from django.contrib import admin
from django.utils.functional import curry


class AlbumInline(admin.StackedInline):
    form = AlbumAdminForm
    model = Album
    extra = 1

    def get_formset(self, request, obj=None, **kwargs):
        formset = super(AlbumInline, self).get_formset(request, obj, **kwargs)
        formset.form.__init__ = curry(formset.form.__init__, request=request)
        return formset

这样可行,但这个解决方案是否是线程安全的?如果不是,我该如何解决?

2 个答案:

答案 0 :(得分:0)

我不认为它是线程安全的,因为咖喱会绑定请求。

但是因为它在管理员中,所以它可能并不重要。

答案 1 :(得分:0)

这似乎不是线程安全的。根据您要从HTTP请求对象中使用的内容,您可以将其复制到新的HttpRequest,并使其仅包含线程安全信息(即大多数信息减去请求线程锁定)。

在我的情况下,我使用这样的东西:

METACOPY = ['HTTP_X_REAL_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR', 'REMOTE_HOST', 'SERVER_NAME', 'SERVER_PORT', 'LANG', 'LANGUAGE', 'HTTP_REFERER']
def thread_safe_copy(self):
    meta = dict([(k,self.META[k]) for k in METACOPY if k in self.META and isinstance(self.META[k], str)])
    request = HttpRequest()
    request.POST = self.POST
    request.GET = self.GET
    request.user = self.user
    request.path = self.path
    request.META = meta
    ...
    return request

在这里,我修补了HttpResponse和WSGIResponse,但你可以用请求实例替换self。