Django Simple Captcha - установка и настройка
На некоторых страницах своего интернет магизина где есть формы авторизации, регистрации и др. решил прикрутить django simple captcha для защиты от ботов. В этой статье я поделюсь опытом установки и настройки этого расширения для django. Сама библиотека находится здесь
Библиотеку можн скачать и закинуть в свой проект или же установить с помощью команды в консоле.
Установка django simple captcha
1.Выполняем команду pip install django-simple-captcha
2.Добавляем 'captcha' в INSTALLED_APPS в файле settings.py
3.Выполняем миграцию python manage.py migrate
В файле urls.py проекта добавляем маршрут
urlpatterns += [
path('captcha/', include('captcha.urls')),
]
Обязательно нужно установить библиотеку Pillow без нее капча работать не будет!
pip install pillow
Теперь в форму где будет выводится капча добавляем поле капчи
captcha = CaptchaField()
from django import forms
from captcha.fields import CaptchaField
class CaptchaTestModelForm(forms.ModelForm):
captcha = CaptchaField()
class Meta:
model = MyModel
Настройка и отображение капчи
В документации есть все основные настроки для работы капчи, которые можно менять на свое усмотрение.
Что бы капча отобразилась на сайте нужно в файле settings.py указать один обязательный параметр.
CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge'
И в шаблоне вывести ее этой переменной в моем случае это так.
{{ form.captcha }}
Так же можно вывести ошибку капчи при неправильно введем проверочном коде этой переменной.
{{ form.captcha.errors }}
И еще можно повесить лейбл над капчей. Для этого в поле капчи которое мы добавляли в форму нужно прописать дополнительный параметр label='Are you an human? '
class CaptchaTestModelForm(forms.ModelForm):
captcha = CaptchaField(label='Are you an human? ')
class Meta:
model = MyModel
И вывести в шаблоне так
{{ form.captcha.label }}
Чтоб была возможность обновить капчу я сделал кнопку и применил яваскрипт из документации капчи.
Вот кнопка в которую я добавил в шаблон с классом captcha-refresh
<button class='captcha-refresh'>
<img src="{% static 'info/news/icon/reload.png' %}">
</button>
И на эту кнопку я повеcил яваскрипт который динамически обновляет капчу
<script type="text/javascript">
$(document).ready(function() {
// Add refresh button after field (this can be done in the template as well)
// {#$('img.captcha').after(#}
// {# $('<a href="#void" class="captcha-refresh">Refresh</a>')#}
// {# );#}
// Click-handler for the refresh-link
$('.captcha-refresh').click(function(){
var $form = $(this).parents('form');
var url = location.protocol + "//" + window.location.hostname + ":"
+ location.port + "/captcha/refresh/";
// Make the AJAX-call
$.getJSON(url, {}, function(json) {
$form.find('input[name="captcha_0"]').val(json.key);
$form.find('img.captcha').attr('src', json.image_url);
});
return false;
});
});
</script>
Чтоб скрипт работал нужно подгрузить jquery в ваш шаблон.
<script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
В итоге у нас должна получиться вот такая капча
И последнее в settings.py можно именять ее по своему желанию. Как писал выше в документации есть основные настройки капчи их нужно указать в вашем файле settings.py. В моем случае я сделал шесть настроек.
CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge'
CAPTCHA_IMAGE_SIZE = (150, 50)
CAPTCHA_FONT_SIZE = (28)
CAPTCHA_BACKGROUND_COLOR = '#cccccc'
CAPTCHA_FOREGROUND_COLOR = '#001100'
CAPTCHA_LENGTH = 6
Подробно не буду расписывать что делает каждая настройка но в общих чертах изменил цвет, размер и количество символов в капчи. В документации там много всяких настроек это уже каждый для себя может пробовать.
Все.
Сейчас у нас капча работает как для зарегистрированных пользователей так и для не зарегистрированных. Согласитесь было бы не логично заставлять зарегистрированного и авторизированного пользователя вводить проверочный код капчи например к статьям сайта или добавлению комментариев. В моем случае на сайте может оставить комментарий как зарегистрированный пользователь так и нет. Поэтому я поставил задачу сделать добавление статей и комментариев на сайт зарегистрированными пользователями без проверки капчи.
Самый простой вариант это сделать вторую форму где не будет поля капчи и уже во вьюхе подсовывать именно эту форму для авторизованного пользователя.
Давайте приступим к реализации этой задачи.
Делаем вторую такую же форму только без поля капчи. Покажу на вымышленном примере.
from django import forms
from captcha.fields import CaptchaField
# Допустим это форма комментариев без капчи
class CommentForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ['user', 'user_name', 'email', 'text']
# Допустим это форма комментариев с капчей
class CommentFormCaptcha(forms.ModelForm):
captcha = CaptchaField()
class Meta:
model = MyModel
fields = ['user', 'user_name', 'email', 'text']
Теперь мы должны получить во views.py наши формы. Импортируем их во вьюху и делаем примерно такую вьюху (взял вьюху из доки для прмера).
def some_view(request):
# Определяем форму без капчи
form_user = CommentForm()
# Определяем форму с капчей
form = CommentFormCaptcha()
# Делаем проверку, если пользователь не авторизован то показываем ему форму с капчей.
if not request.user.is_authenticated:
form = CommentFormCaptcha(request.POST or None)
if request.method == 'POST':
if form.is_valid():
human = True
else:
form = CommentFormCaptcha()
# Если пользователь авторизован то показываем ему форму без капчи.
else:
form_user = CommentForm(request.POST or None)
if request.method == 'POST':
if form_user.is_valid():
human = True
else:
form = CommentForm()
return render(request, 'news/details.html', {'form': form, 'form_user ': form_user})
В шаблоне ничего править не нужно. Таким образом не зарегистрированные пользователи могут оставлять свои комментарии в моем случае с проверкой капчи а зарегистированные могут оставлять комменты без проверки капчи.
На этом все.
Ваши комментарии
Комментарии могут оставлять только зарегистрированые пользователи!