Python Django 1.11 TypeError 上下文必须是 dict 而不是 Context
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43787700/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Django 1.11 TypeError context must be a dict rather than Context
提问by Studio Rooster
Just received the Sentry error TypeError context must be a dict rather than Context.
on one of my forms. I know it has something to do with Django 1.11, but I am not sure what to change to fix it.
刚刚TypeError context must be a dict rather than Context.
在我的一张表格上收到了 Sentry 错误。我知道它与 Django 1.11 有关,但我不确定要更改什么来修复它。
Offending line
违规行
message = get_template('email_forms/direct_donation_form_email.html').render(Context(ctx))
message = get_template('email_forms/direct_donation_form_email.html').render(Context(ctx))
Entire View
全视图
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)
回答by Alasdair
In Django 1.8+, the template's render
method takes a dictionary for the context
parameter. Support for passing a Context
instance is deprecated, and gives an error in Django 1.10+.
在Django 1.8+ 中,模板的render
方法接受一个字典作为context
参数。不推荐支持传递Context
实例,并在 Django 1.10+ 中出现错误。
In your case, just use a regular dict
instead of a Context
instance:
在您的情况下,只需使用常规dict
而不是Context
实例:
message = get_template('email_forms/direct_donation_form_email.html').render(ctx)
You may prefer to use the render_to_string
shortcut:
您可能更喜欢使用render_to_string
快捷方式:
from django.template.loader import render_to_string
message = render_to_string('email_forms/direct_donation_form_email.html', ctx)
If you were using RequestContext
instead of Context
, then you would pass the request
to these methods as well so that the context processors run.
如果您使用的是RequestContext
而不是Context
,那么您也会将 传递request
给这些方法,以便上下文处理器运行。
message = get_template('email_forms/direct_donation_form_email.html').render(ctx, request=request)
message = render_to_string('email_forms/direct_donation_form_email.html', ctx, request=request)
回答by VIctor Angelov
Migrated from Django 1.8 to Django 1.11.6
从 Django 1.8 迁移到 Django 1.11.6
Wherever i had a RequestContext class, there is a method flatten() wich return the result as a dict.
无论我在哪里有 RequestContext 类,都有一个方法 flatten() 将结果作为 dict 返回。
So if the class is RequestContext....
所以如果类是 RequestContext ....
return t.render(context)
becomes
变成
return t.render(context.flatten())
And in a case wich the context is is wrapped by Context(), just remove it. Because Context() is deprecated.
在上下文由 Context() 包装的情况下,只需将其删除。因为 Context() 已被弃用。
return t.render(Context(ctx))
becomes
变成
return t.render(ctx)
回答by Yvette Tan
For django 1.11 and after, context must be dict.
对于 django 1.11 及之后的版本,上下文必须是 dict。
You can use:
您可以使用:
context_dict = get_context_dict(context)
return t.render(context_dict)
or
或者
context_dict = context.flatten()
return t.render(context_dict)