Je viens de recevoir l'erreur Sentry TypeError context must be a dict rather than Context.
sur l'un de mes formulaires. Je sais que cela a quelque chose à voir avec Django 1.11, mais je ne sais pas quoi changer pour le réparer.
Ligne incriminée
message = get_template('email_forms/direct_donation_form_email.html').render(Context(ctx))
vue complète
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)
Dans Django 1.8 + , la méthode render
du modèle prend un dictionnaire pour le paramètre context
. Prise en charge de la transmission d'une instance Context
obsolète , et erreur dans Django 1.10+.
Dans votre cas, utilisez simplement une instance normale de dict
au lieu d'une instance de Context
:
_message = get_template('email_forms/direct_donation_form_email.html').render(ctx)
_
Vous préférerez peut-être utiliser le raccourci render_to_string
:
_from Django.template.loader import render_to_string
message = render_to_string('email_forms/direct_donation_form_email.html', ctx)
_
Si vous utilisiez RequestContext
au lieu de Context
, vous passeriez alors le request
à ces méthodes afin que les processeurs de contexte s'exécutent.
_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)
_
Migration de Django 1.8 à Django 1.11.6
Partout où j'ai eu une classe RequestContext, il existe une méthode flatten () qui renvoie le résultat sous forme de dict.
Donc, si la classe est RequestContext ....
return t.render(context)
devient
return t.render(context.flatten())
Et dans un cas où le contexte est enveloppé par Context (), supprimez-le simplement. Parce que Context () est obsolète.
return t.render(Context(ctx))
devient
return t.render(ctx)
Pour Django 1.11 et les suivants, le contexte doit être dicté.
Vous pouvez utiliser:
context_dict = get_context_dict(context)
return t.render(context_dict)
ou
context_dict = context.flatten()
return t.render(context_dict)