1

I want to send a html email to some address.

This is part of my code:

views.py

def addNewEvent(request):   
    try:
        eventStatus = EventStatus.objects.filter(event=request.GET["id"])[0]

        #try to send the mail
        html = get_template('mail.html')
        d = Context({ 'username': usuario.name,'title':'Testing mail!!','eventStatusId': str(eventStatus.id)})

        html_content = html.render(d)

        msg = EmailMultiAlternatives('Testing yo','Skyforger!', 'mymail@gmail.com', [mail2@gmail.com])
        msg.attach_alternative(html_content, "text/html")
        msg.send()

        print('EventStatus id '+str(eventStatus.id))
    except Exception, e:
        print ('the error %s',(str(e)))

    response = getBaseJSON()
    response["event_id"]= eventStatus.id
    return HttpResponse(json.dumps(response), content_type="application/json")

mail.html

<html>
    <body>
        <h1>{{title}}</h1>
        <h2>Hi {{username}}</h2>
        <h3>Message to friend</h3>
        <form action="http://localhost:8000/confirmEvent" method="POST">
            {% csrf_token %}
            <input type="hidden" name="id" value="{{eventStatusId}}">
            <textarea name="message_to_friend"></textarea><br>
            <input type="submit" value="I'LL BE THERE!!">
        </form>
    </body>
</html>

The mail is sent OK, but when its form is submitted, this error is displayed:

Forbidden (403) CSRF verification failed. Request aborted.

I can't find how to solve that error.

I followed many answers like these:

https://stackoverflow.com/a/10388110

Forbidden (403) CSRF verification failed. Request aborted. Even using the {% csrf_token %}

with no success.

How can I send the form inside the html mail avoiding the CSRF error.

Community
  • 1
  • 1
Boel
  • 917
  • 2
  • 11
  • 23
  • 1
    I see that you have seen the answers, but I dont see the `{% csrf_token %}` in your form – karthikr Jul 31 '14 at 00:46
  • 1
    Just to be clear, is the mail.html rendered and sent to the user who opens it in their mail client? The CSRF token corresponds to the *current user*, not the user who will open it in their mail. Furthermore, because you use Context() to render the form there is a strong likelihood that the CSRF token is not included. You are supposed to use RequestContext: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/ – mgnb Jul 31 '14 at 05:05
  • @mgnb how should I use the RequestContext in my case? I read it must be used as a param inside render_to_response, but I'm not using that method – Boel Jul 31 '14 at 12:14

2 Answers2

1

You can use the csrf_exempt decorator to disable CSRF protection for a particular view.

from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def someview():

Its not recommended to disable csrf , but you can try this if you want :)

Inforian
  • 1,716
  • 5
  • 21
  • 42
0

I replaced render() by render_to_string() with the param context_instance=RequestContext(request) and now this is working.

def addNewEvent(request):   
        try:
            eventStatus = EventStatus.objects.filter(event=request.GET["id"])[0]

            #try to send the mail
            html = get_template('mail.html')
            d = Context()

            html_content = render_to_string('mail.html',{ 'username': usuario.name,'title':'Testing mail!!','eventStatusId': str(eventStatus.id)}, context_instance=RequestContext(request)) 
            msg = EmailMultiAlternatives('Testing yo','Skyforger!', 'mymail@gmail.com', [mail2@gmail.com])
            msg.attach_alternative(html_content, "text/html")
            msg.send()

            print('EventStatus id '+str(eventStatus.id))
        except Exception, e:
            print ('the error %s',(str(e)))

        response = getBaseJSON()
        response["event_id"]= eventStatus.id
        return HttpResponse(json.dumps(response), content_type="application/json")
Boel
  • 917
  • 2
  • 11
  • 23