Django 1.11 TypeError上下文必须是dict而不是Context

Stu*_*ter 43 python django django-views

TypeError context must be a dict rather than Context.在我的一个表单上收到了Sentry错误.我知道它与Django 1.11有关,但我不知道要修改什么来修复它.

违规线

message = get_template('email_forms/direct_donation_form_email.html').render(Context(ctx))

整个视图

def donation_application(request):
    if request.method == 'POST':
        form = DirectDonationForm(data=request.POST)
        if form.is_valid():
            stripe.api_key = settings.STRIPE_SECRET_KEY
            name = request.POST.get('name', '')
            address = request.POST.get('address', '')
            city = request.POST.get('city', '')
            state = request.POST.get('state', '')
            zip = request.POST.get('zip', '')
            phone_number = request.POST.get('phone_number', '')
            support = request.POST.get('support', '')
            agree = request.POST.get('agree', '')
            email_address = request.POST.get('email_address', '')
            number = request.POST.get('number', '')
            cvc = request.POST.get('cvc', '')
            exp = request.POST.get('exp', '')
            # token = form.cleaned_data['stripe_token'],
            # exp_m = int(request.POST.get('exp_month', ''))
            # exp_y = int(request.POST.get('exp_year', ''))

            exp_month = exp[0:2]
            exp_year = exp[5:9]

            subject = 'New Donation'
            from_email = settings.DEFAULT_FROM_EMAIL
            recipient_list = ['deniselarkins@/////\\\\\.com',
                              'charles@/////\\\\\.net',
                              'marcmunic@/////\\\\\.com',
                              ]

            token = stripe.Token.create(
                card={
                    'number': number,
                    'exp_month': exp_month,
                    'exp_year': exp_year,
                    'cvc': cvc
                },
            )

            customer = stripe.Customer.create(
                email=email_address,
                source=token,
            )

            total_support = decimal.Decimal(support) / 100
            total_charge = decimal.Decimal(int(support)) / 100

            # Charge the user's card:
            charge = stripe.Charge.create(
                amount=total_charge,
                currency='usd',
                description='Donation',
                customer=customer.id
            )

            ctx = {
                'name': name,
                'address': address,
                'city': city,
                'state': state,
                'zip': zip,
                'phone_number': phone_number,
                'email_address': email_address,
                'agree': agree,
                'charge': charge,
                'customer': customer,
                'total_support': total_support,
                'total_charge': total_charge
            }

            message = get_template('email_forms/direct_donation_form_email.html').render(Context(ctx))
            msg = EmailMessage(subject, message, from_email=from_email, to=recipient_list)
            msg.content_subtype = 'html'
            msg.send(fail_silently=True)

            return redirect(
                '/contribute/donation-support-thank-you/?name=' + name +
                '&address=' + address +
                '&state=' + state +
                '&city=' + city +
                '&zip=' + zip +
                '&phone_number=' + phone_number +
                '&email_address=' + email_address +
                '&total_support=' + str(total_support) +
                '&total_charge=' + str(total_charge)
            )
    context = {
        'title': 'Donation Pledge',
    }

    return render(request, 'contribute/_donation-application.html', context)
Run Code Online (Sandbox Code Playgroud)

Ala*_*air 56

Django 1.8+中,模板的render方法采用context参数字典.不推荐支持传递Context实例,并在Django 1.10+中出错.

在您的情况下,只需使用常规dict而不是Context实例:

message = get_template('email_forms/direct_donation_form_email.html').render(ctx)
Run Code Online (Sandbox Code Playgroud)

您可能更喜欢使用render_to_string快捷方式:

from django.template.loader import render_to_string

message = render_to_string('email_forms/direct_donation_form_email.html', ctx)
Run Code Online (Sandbox Code Playgroud)

  • @DavidTorrey如果手动构造一个`django.template.Template`,那么你仍然需要传递一个`Context`实例.根据你是否使用`template = Template(...)`或`template = get _template(...)`,API有点混乱. (5认同)

VIc*_*lov 10

从Django 1.8迁移到Django 1.11.6

无论我有什么RequestContext类,都有一个方法flatten()将结果作为dict返回.

所以如果这个类是RequestContext ....

return t.render(context)
Run Code Online (Sandbox Code Playgroud)

return t.render(context.flatten())
Run Code Online (Sandbox Code Playgroud)

在上下文被Context()包装的情况下,只需将其删除即可.因为不推荐使用Context().

return t.render(Context(ctx))
Run Code Online (Sandbox Code Playgroud)

return t.render(ctx)
Run Code Online (Sandbox Code Playgroud)