Django3.2.12用django-mjml报错:Context对象无render_context属性
问题
运行Django==3.2.12,使用django-mjml生成渲染后的模板字符串,此前功能正常,现在出现错误:'Context' object has no attribute 'render_context'。
相关代码
import uuid from django.db import models from django.template import Template, Context from django.urls import reverse class EmailTemplate(models.Model): name = models.CharField(max_length=255) slug = models.SlugField(max_length=255, unique=True) uuid = models.UUIDField(default = uuid.uuid4) mjml_template = models.TextField(blank=True) html_template = models.TextField(blank=True) class Meta: ordering = ['name', ] verbose_name = 'Template' verbose_name_plural = 'Templates' def __str__(self): return self.name def get_absolute_url(self): return reverse('pages:emailing', kwargs={'slug': self.slug, 'uuid': self.uuid}) def save(self, *args, **kwargs): mjml_open = '{% load mjml %}{% mjml %}' mjml_close = '{% endmjml %}' verbatum_open = '{% verbatim %}{{' verbatum_close = '}}{% endverbatim %}' verbatum = self.mjml_template.replace('{{', verbatum_open) verbatum = verbatum.replace('}}', verbatum_close) verbatum = mjml_open + verbatum + mjml_close template = Template(verbatum) context = Context({}) passed = False try: self.html_template = template.render(context) passed = True except Exception as err: self.html_template = str(err) if passed: image_categories = ImageCategory.objects.filter(templates=self) for image_category in image_categories: for image in image_category.get_images(): tag = '[~ ' + image.slug + ' ~]' swap = self.html_template swap = swap.replace(tag, image.image.url) self.html_template = swap resource_categories = ResourceCategory.objects.filter(templates=self) for resource_category in resource_categories: for resource in resource_category.get_resources(): tag = '[~ ' + resource.slug + ' ~]' swap = self.html_template swap = swap.replace(tag, resource.resource) self.html_template = swap super(EmailTemplate, self).save(*args, **kwargs)
报错回溯
Internal Server Error: /admin/emailing/emailtemplate/1/change/ Traceback (most recent call last): File "/Users/sbrown/.local/share/virtualenvs/mjml-NNm5TF3H/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner response = get_response(request) File "/Users/sbrown/.local/share/virtualenvs/mjml-NNm5TF3H/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/Users/sbrown/.local/share/virtualenvs/mjml-NNm5TF3H/lib/python3.9/site-packages/django/contrib/admin/options.py", line 616, in wrapper return self.admin_site.admin_view(view)(*args, **kwargs) File "/Users/sbrown/.local/share/virtualenvs/mjml-NNm5TF3H/lib/python3.9/site-packages/django/utils/decorators.py", line 130, in _wrapped_view response = view_func(request, *args, **kwargs) File "/Users/sbrown/.local/share/virtualenvs/mjml-NNm5TF3H/lib/python3.9/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func response = view_func(request, *args, **kwargs) File "/Users/sbrown/.local/share/virtualenvs/mjml-NNm5TF3H/lib/python3.9/site-packages/django/contrib/admin/sites.py", line 232, in inner return view(request, *args, **kwargs) File "/Users/sbrown/.local/share/virtualenvs/mjml-NNm5TF3H/lib/python3.9/site-packages/django/contrib/admin/options.py", line 1660, in change_view return self.changeform_view(request, object_id, form_url, extra_context) File "/Users/sbrown/.local/share/virtualenvs/mjml-NNm5TF3H/lib/python3.9/site-packages/django/utils/decorators.py", line 43, in _wrapper return bound_method(*args, **kwargs) File "/Users/sbrown/.local/share/virtualenvs/mjml-NNm5TF3H/lib/python3.9/site-packages/django/utils/decorators.py", line 130, in _wrapped_view response = view_func(request, *args, **kwargs) File "/Users/sbrown/.local/share/virtualenvs/mjml-NNm5TF3H/lib/python3.9/site-packages/django/contrib/admin/options.py", line 1540, in changeform_view return self._changeform_view(request, object_id, form_url, extra_context) File "/Users/sbrown/.local/share/virtualenvs/mjml-NNm5TF3H/lib/python3.9/site-packages/django/contrib/admin/options.py", line 1586, in _changeform_view self.save_model(request, new_object, form, not add) File "/Users/sbrown/.local/share/virtualenvs/mjml-NNm5TF3H/lib/python3.9/site-packages/django/contrib/admin/options.py", line 1099, in save_model obj.save() File "/Applications/MAMP/htdocs/mjml/emailing/models.py", line 42, in save self.html_template = template.render(context) File "/Users/sbrown/.local/share/virtualenvs/mjml-NNm5TF3H/lib/python3.9/site-packages/django/template/base.py", line 166, in render with context.render_context.push_state(self): AttributeError: 'Context' object has no attribute 'render_context'
解决方案
这个错误的核心原因是:Django 3.2的模板渲染API要求上下文对象具备render_context属性,手动创建的Context实例不符合该要求。
有两种简单的修复方式:
方式一:直接传递字典作为上下文
无需手动创建Context对象,直接将字典传入template.render()方法,Django会自动处理上下文的创建:
# 替换原来的context = Context({})和template.render(context) self.html_template = template.render({})
方式二:确保使用正确的上下文类
如果需要显式创建上下文,可直接使用django.template.context.Context(虽然Django 3.2中from django.template import Context已指向该类,但环境中可能存在导入混淆)。不过在model的save方法中无request对象,因此更推荐方式一。
另外,建议检查django-mjml版本是否兼容Django 3.2,可升级至最新稳定版的django-mjml包。
内容的提问来源于stack exchange,提问作者Stephen Brown
相关产品推荐
相关产品推荐

