Django Simple Captcha - установка и настройка

    blazer |   20.02.2019 |   20:41:33 |   Django |

На некоторых страницах своего интернет магизина где есть формы авторизации, регистрации и др. решил прикрутить 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})

В шаблоне ничего править не нужно. Таким образом не зарегистрированные пользователи могут оставлять свои комментарии в моем случае с проверкой капчи а зарегистированные могут оставлять комменты без проверки капчи.
На этом все.

 

Ваши комментарии

Комментарии могут оставлять только зарегистрированые пользователи!

Disqus - комментарии

blog comments powered by Disqus