web-dev-qa-db-fra.com

Django 1.11 Le contexte TypeError doit être un dict plutôt que du contexte.

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)
41
Studio Rooster

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 Contextobsolè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)
_
53
Alasdair

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)
9
VIctor Angelov

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)
0
Yvette Tan