【问题标题】:Django TypeError: render() takes 2 positional arguments but 3 were given?Django TypeError:render() 接受 2 个位置参数但给出了 3 个?
【发布时间】:2018-09-04 13:18:17
【问题描述】:

我正在从我的员工网站向我的司机发送一封电子邮件,但我无法发送带有 url 链接的司机 ID。我得到了错误:

join_message = template.render(ctx, request)**
TypeError: render() takes 2 positional arguments but 3 were given**

我的看法:

def rentacar_carapp_approve(request):
    if request.POST:
        try:
            args['driver'] = driver = Driver.objects.get(id=request.POST.get('driver_id'))
            subject = "Please Register Your Car"
            from_email = settings.EMAIL_HOST_USER
            to_email = 'bakrshk@gmail.com'
            if to_email is not None:
                template = Template("""Please hit the link and book a car {{ request.get_host }}{% url 'detail' driver_id=driver_id %}""")
                ctx = Context({'driver_id': driver.id})
                join_message = template.render(ctx, request)
                send_mail(subject=subject, from_email=from_email, recipient_list=[to_email], message=join_message,
                          fail_silently=False)
                print("email sent")
        except Driver.DoesNotExist:
            print("Driver doesn't exists")
        return HttpResponseRedirect('/mega-admin/rentacar/carapp-manager/')

【问题讨论】:

    标签: python django django-views


    【解决方案1】:

    要将request 传递给模板上下文,您可以将其显式包含在上下文中:

    template = Template("""Please hit the link and book a car {{ request.get_host }}{% url 'detail' driver_id=driver_id %}""")
    ctx = Context({'driver_id': driver.id, 'request': request})
    join_message = template.render(ctx, request)
    

    或者您可以使用RequestContext(假设您启用了请求上下文处理器。

    template = Template("""Please hit the link and book a car {{ request.get_host }}{% url 'detail' driver_id=driver_id %}""")
    ctx = RequestContext(request, {'driver_id': driver.id})
    join_message = template.render(ctx, request)
    

    请注意,从字符串实例化模板是不常见的(例如template = Template("""..."""))。通常,您会将模板保存到模板目录中的文件中(例如car_approve.email),然后使用render_to_string 快捷方式来呈现模板。 render_to_string 模板确实接受 request 作为参数。

    from django.template.loader import render_to_string
    context = {'driver_id': driver.id}
    join_message = render_to_string('car_approve.email', context, request=request)
    

    【讨论】:

    • 感谢您纠正我的问题并给出精彩的回答。 Alasdir 我必须在我的模板目录中创建一个模板还是我通过这个。
    • 前两个选项只是对代码的更改,它们仍然使用template = Template("""...""")。第三个选项要求您在templates 目录中创建一个包含Please hit the link... 的文件。这取决于您选择哪个选项,但第三个选项是最佳实践,因为它将模板与代码分开。
    • 再次感谢您。 Alasdair 你能把链接或一些例子发给我吗?第三个选项怎么做。制作一个文件,请点击链接。
    • 创建模板文件很简单。这是covered in the tutorial
    • 谢谢@ALasdair
    【解决方案2】:

    你不应该给请求参数。

    https://docs.djangoproject.com/en/2.1/ref/templates/api/#django.template.Template

    为了解释错误消息,您为渲染方法提供了 2 个参数,该方法绑定到模板实例。这个“函数”实际上接收 3 个参数,第一个是“self”(您的模板实例)。

    【讨论】:

    • 所以如果我想通过所有三个我应该怎么做?
    【解决方案3】:

    首先,您需要从join_message = template.render(ctx, request) 中删除request 并使用join_message = template.render(ctx)

    docs

    然后正确构建它:

    template = Template("""Please hit the link and book a car {{ booking_link }}""")
    ctx = Context({'booking_link': request.build_absolute_uri(reverse('detail', kwargs={'driver_id': driver_id}))})
    join_message = template.render(ctx)
    

    build_absolute_uri docs

    reverse docs

    我没有对其进行测试,但它应该会返回您要查找的内容...

    【讨论】:

    • 我删除了请求,它没有发送 url 路径。请点击链接并预订汽车/drivers/2/
    • 更新了我的答案以使用 Django 的内置工具生成 url
    • 但我的目录的 url 不显示只是 /drivers/1/ 是在电子邮件中生成的。驱动程序 id 是正确的,但 url 路径没有它
    • 先生,我如何用作模板\
    • 我以为你已经选择了正确的答案?有什么问题?
    猜你喜欢
    • 2015-04-18
    • 2020-08-12
    • 1970-01-01
    • 2022-01-17
    • 2019-09-21
    • 2019-07-19
    • 2021-02-02
    • 2020-02-07
    • 2017-03-14
    相关资源
    最近更新 更多