我有一个系统,我需要在请求之前和之后对URL进行完全动态控制。
我正在使用信号,对于预请求信号(我遇到问题的信号,我有一个这样的中间件,它连接到信号,允许它检查当前的请求.path适用于它,然后与它获得的第一个一起使用。这通常工作正常,并且相当优雅):
class PreRouteMiddleWare(object):
def process_request(self, request):
url = request.path.strip('/')
if url == '':
url = '/'
pre_routes = pre_route.send(sender=request, url=url)
for reciever, response in pre_routes:
if response:
return response
return None
现在,为了注册Django路由堆栈之前发生的事情,我在应用程序models.py
中做了类似的事情:
@receiver(pre_route)
def try_things(sender, url, **kwargs):
try:
thing= Thing.objects.get(url=url)
from myapp.views import myview
return myview(sender, some_args)
except Thing.DoesNotExist:
return False
这在我的开发服务器上也很有用。
然而,问题出现在我使用uWSGI的生产中。我从这个开始uWSGI(来自暴发户):
sudo /usr/local/bin/uwsgi --emperor '/srv/*/uwsgi.ini' --enable-threads --single-interpreter
我的uwsgi.ini看起来像这样:
[uwsgi]
socket = /srv/new/uwsgi.sock
module = wsgi:app
chdir = /srv/new/myapp
virtualenv = /srv/new
env = DJANGO_SETTINGS_MODULE=myapp.settings
uid = wsgi_new
gid = www-data
chmod = 770
processes = 2
似乎正在发生的事情是每个uWSGI进程/线程,它们似乎只在第一个请求上加载models.py,这意味着每个进程的第一个请求将无法连接信号。这意味着我有n(其中n是进程数)请求完全失败,因为在启动时没有加载models.py(因为它正在开发中)。
我配置uWSGI错了吗?是否有更好的方法强制在启动时连接信号?
答案 0 :(得分:3)
Django实际上懒得加载东西。使用开发服务器会对真实WSGI服务器中的工作方式产生错误的安全感,因为开发服务器加载管理命令会强制进行生产服务器不会发生的大量早期初始化。
你可能会读到:
http://blog.dscpl.com.au/2010/03/improved-wsgi-script-for-use-with.html
解释了mod_wsgi中出现的问题。 uWSGI也会发生同样的事情。
答案 1 :(得分:0)
好的,事实证明我需要制作我的中间件钩子process_view而不是process_request:
class PreRouteMiddleWare(object):
def process_view(self, request, *args, **kwargs):
url = request.path.strip('/')
if url == '':
url = '/'
pre_routes = pre_route.send(sender=request, url=url)
for reciever, response in pre_routes:
if response:
return response
return None
现在效果很好!