Today I wanna talk about some details on how to send an email using Django, along with some brief introduction towards CSRF protection in django.
Structure of today’s blog:
1. CSRF
2. Implementation of sending an email using django
3. Some insignificant trouble met these days
Part 1: CSRF Protection
The CSRF protection is called ‘cross site request forgery protection’, the graph below shows how Web B could gain information from Web A using User C’s license without letting User C know.[[1]]
Django CSRF protection works by checking for a nonce in each POST request. This ensures that a malicious user cannot simply ‘reply’ a form POST to your Web site and have another logged in user unwittingly submit that form. The malicious user would have to know the nonce, which is user specific (using a cookie). [[2]]
Part 2: Implementation
This part has 2 implementations, one with global setting CSRF closed, contrast to the other one with CSRF protection.
I). Without CSRF protection[[3]]:
a). Disable the CSRF module globally
#settings.py
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
***# Annotate the order below***
***#'django.middleware.csrf.CsrfViewMiddleware',***
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
)
b). Implement sending email
#settings.py
EMAIL_HOST='smtp.sina.com'
EMAIL_PORT=25
EMAIL_HOST_USER='YOUR_EMAIL_ADDRESS'
EMAIL_HOST_PASSWORD='YOUR_PASSWORD'
EMAIL_SUBJECT_PREFIX=u'django'
EMAIL_USE_TLS=True
#views.py
def setEmail(request):
if request.method=='POST':
send_mail('subject', 'this is a msg of email', 'EMAIL_ADDRESS', ['EMAIL_ADDRESS'])
return HttpResponse(u'Successfully sent')
return render_to_response('contact_form.html')
#urls.py
#Add this in urlpatterns
url(r'^setEmail/$', setEmail)
II). With CRSF protection[[4]]:
Flows:
a). The CSRF middleware is activated by default in the MIDDLEWARE_CLASSES setting, if you wanna override that setting, please do remember that ‘django.middleware.csrf.CsrfViewMiddleware’ should always come before any view middleware that assume that CSRF attacks have been dealt with. And if you disabled it like me ahead, you should have use csrf_protect() on particular views you wanna protect, and this is not recommended.
b). In any template that uses a POST form, use the csrf_token tag inside the ‘form’ tag, e.g.:
<form action="" method='post'>{% csrf_token %}
c). In the corresponding view functions, ensure that the ‘django.template.context_processors.csrf’ context processor is being used. Usually, this can be done in one of two ways:
c.1) Use RequestContext, which always uses ‘django.template.context_processor.csrf’ (no matter what template context processor are configured in the TEMPLATES settings).
c.2) Manually import and use the processor to generate the CSRF token and add it to the template context. e.g.:
from django.template.context_processors import csrf
def my_view(request):
c={}
c.update(csrf(request))
#...view code here
return render_to_response('a_template.html', c)
Mine is here:
#views.py
from django.template.context_processors import csrf
def contact(request):
if request.method=='POST':
form=ContactForm(request.POST)
if form.is_valid():
c={}
c.update(csrf(request))
cd=form.cleaned_data
send_mail(
cd['subject'],
cd['message'],
cd.get('email', 'EMAIL_ADDRESS'),
['EMAIL_ADDRESS'],
)
return render_to_response('contact_form.html', locals(), context_instance=RequestContext(request))
#return HttpResponseRedirect('/contact/thanks/')
else:
form=ContactForm()
c={}
c.update(csrf(request))
return render_to_response('contact_form.html', locals(), context_instance=RequestContext(request))
Finally, we can send emails.
Part 3: Some insignificant problems I met
Today I load django on my new ubuntu PC and confronted a problem when I create my first project. I use ‘pip’ to install django without using ‘sudo’, that is, I install django without authority of the root user. Defaultly, django file should be installed to the file under where the file python is. However, without authority, I pip the django into another dictionary and I just could not find it.
In fact, I should have used instruction ‘pip show django’ to find out its location. With the authority of the super user, it works out well.
Another problem lays in MySQL database. First, when I enter into mysql from shell I type in ‘show databases’ contrasting to the correct syntax ‘show databases;’, I then realize my fault and sequently type in the correct instruction. However, this could not run successfully. I must type in the right order the first time, it’s wired. Because of my recent focus on python, I always forget to add ‘;’ in mysql. More instruction could be seen at [[5]].
Yet I still meet another trouble. I wanna link to mysql from django, but whenever I type in ‘python manage.py shell’, it always throw an ”’django.core.exceptions.ImproperlyConfigured: You must define a ‘default’ database”’, I have the correct setting.py. Finally, it is because I use this -> ”’blablabla”’ to comment or we say to annotate while django does not take it as an annotation. I should have used ‘#’ to comment orders. ==.
References:
[1] http://www.wpython.com/361.html
[2] https://docs.djangoproject.com/en/1.8/topics/security/
[3] http://www.cnblogs.com/BeginMan/p/3443158.html
[4] https://docs.djangoproject.com/en/1.8/ref/csrf/
[5] http://blog.knowsky.com/186050.html