Closed xurwxj closed 10 years ago
You can serialize (pickle and friends), but i strongly suggest you to not do it. Work by references, passing the id/pk of the objects to the spooler and similar. You have to consider it as an external system
It's quite painful, we do pass the pk or string value. But unable to find the template to render with: [code] import sys, os try: import uwsgi sys.path.insert(0, uwsgi.opt['chdir']) os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'test.settings') except: pass from django.conf import settings
when with render_tostring, i got: django.template.base.TemplateDoesNotExist: workflow/msg/material
but the template actually exist.
when run without spool, it all ok.
You have to treat the spooler as an external script. Based on the version of Django you need to initialize it. Your approach works (iirc) only for 1.6, 1.7 requires calling django.setup(), older django requires calling setup_environ()
i'm use django 1.7, i tried your method with calling django.setup(), but still get following error:
when with render_to_string, i got: File "./shining3d/libs/workflow/heper.py", line 169, in send_wfmsg ... django.template.base.TemplateDoesNotExist: workflow/msg/material
@spool def flow_init(arguments):
# flow_obj = pickle.loads(arguments['args'])
import django
django.setup()
flow_obj = get_instance_class_id(arguments['flow_obj_class'], arguments['flow_obj_id'])
if flow_obj:
flow_obj.init_flow()
def send_wf_msg(recipients, receiptsummary, msg_type, wf_log=None, wf_node=None, way_list=['mail', 'sms', 'rtx']): import django django.setup() wf_type = receiptsummary.wf_type templates = [ 'workflow/msg/%(wftype)s%(msgtype)s%(msg_part)s.txt', 'workflow/msg/%(msgtype)s%(msg_part)s.txt', 'workflow/msg/%(msg_part)s.html', ] templ_name_dict = {'wf_type': wf_type, 'msg_type': msg_type, 'msg_part': 'subject'} subject_templates = [e % templ_name_dict for e in templates] ctx = {'obj': receiptsummary, 'log': wf_log, 'node': wf_node, 'sys_base_url': settings.SYS_BASE_URL} subject = render_to_string(subject_templates, ctx) templ_name_dict['msg_part'] = 'body' body_templates = [e % templ_name_dict for e in templates] msg_body = render_to_string(body_templates, ctx) send_sys_msg(msg_body, recipients=recipients, subject=subject, way_list=way_list)
all got success without render tempate.
i consider maybe something wrong with loading django template in uwsgi spool.
Honestly it is too django-related, and i fear i am not able to help you, you should search the way to correctly access templates from external scripts. I leave the ticket open, so if someone already faced the issue can help you
thank you, i'll go with your advice and feed back when got solved.
through django management command or python exec file calling in spool is the perfect way for now, can resolve template render and url parse problem, but need transaction roll back control for big thing.
hope uwsgi can load full django env with spool in future.
Sorry, but why you think it is something uWSGI has to manage ? this is at the python level, you can rebuild the same environment like the django command suite does. My previous answer was a simply "i do not know how to do it" (as i never needed to deal with django templates from async jobs) :)
uwsgi load django configure environment, but lost something like template and url related. these all works with django management command or python exec file. for same load method:
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(os.path.realpath(os.path.dirname(inspect.stack()[0][1]))))))
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')
import django
django.setup()
from django.shortcuts import render_to_response
from django.core.urlresolvers import reverse
render_to_response template in uwsgi spool must with template_dir specifacted when works in other environment. and reverse not work in uwsgi spool.
the difference i think is in environment after loaded django configure.
In case someone else comes here (like me), yes, I get the same problem (now with Django 2.2). Even after calling django.setup(), templates are not found but everything else works (I realize this has nothing to do with uwsgi but it must be a pretty common use-case though, spooling email sending and stuff that needs templates).
Edit: I located the problem, the issue is that DjangoTemplates does not find its application dirs (where the templates are located) automagically as it normally does if its config option APP_DIRS is True, if setup stand-alone in the spooler process. So it will look like templates stop working when you try to use them in the spooler. The workaround is to explicitly list the absolute path of the template dirs you need, in the DIRS option (like below) in settings.py:
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ '/mysite/myapp/templates' ], # req. for uWSGI spooler invocation 'APP_DIRS': True, .... }]
Hello fellow developers,
If you are here, you seem to be in confusion and distress. The correct solution for the problem above and others (not having a correctly setup django environment in your uwsgi spooler) is twofold:
--spooler-chdir
to your Django Applications root directory.import django; django.setup(set_prefix=False)
in your tasks.py
This way, the spooler (which should be seen as a completely different python process) will change into the correct location and sets up the Django environment correctly.
Hope this helps someone! Best regards, Dennis
when uwsgi spooler work with django, how to transfer model instance, request, etc. to spooler? also how to get context work in spooler?
uwsgi spooler only support str param now.