Рубрики
Без рубрики

Создание продуктов данных с помощью Python: Добавление управления пользователями на веб-сайт Django

Это второй учебник из нашей серии о том, как создавать продукты данных с помощью Python. В этом втором уроке мы добавим управление пользователями. Это важная часть. Как только мы сможем идентифицировать отдельных пользователей, мы будем готовы генерировать рекомендации пользователей с помощью машинного обучения.

Автор оригинала: Jose A Dianes.

Это второй учебник из нашей серии о том, как создавать продукты данных с помощью Python. Помните, что в качестве лейтмотива мы хотим создать веб-сайт с обзорами и рекомендациями вин, используя технологии Python, такие как Django и Pandas. Мы решили создать веб-сайт отзывов и рекомендаций о вине, но концепции и технологический стек могут быть применены к любому продукту отзывов и рекомендаций пользователей.

Мы хотим, чтобы эти учебные пособия оставили вам продукт, который вы можете адаптировать и показать как часть своего портфолио. С этой целью мы объясним, как настроить виртуальную машину Koding и использовать ее в качестве сервера разработки Django и Pandas + Scikit-learn Python.

В первом уроке мы запустили проект Django и приложение Django для нашего веб-приложения Wine recommender. Все это будет постепенным процессом, за которым может последовать проверка отдельных тегов в нашем репо GitHub . Таким образом, вы можете работать над теми отдельными задачами на данном этапе, которые вам кажутся более интересными или трудными.

В этом втором уроке мы добавим управление пользователями. Это важная часть. Как только мы сможем идентифицировать отдельных пользователей, мы будем готовы генерировать рекомендации пользователей с помощью машинного обучения.

В третьем уроке вы узнаете, как использовать машинное обучение для предоставления рекомендаций нашим пользователям, используя кластеризацию k-means.

Помните, что вы можете следовать учебнику на любом этапе разработки, разветвив репо в свою учетную запись GitHub, а затем клонировав его в свою рабочую область и проверив соответствующий тег. Разветвляя репо, вы можете изменять его по своему усмотрению и экспериментировать с ним столько, сколько вам нужно. Если в какой-то момент вам захочется немного помочь с каким-то шагом урока или сделать его своим собственным, мы можем провести сеанс 1:1 codementor об этом.

Так что давайте продолжим наш проект!

Настройка аутентификации Django

С того самого момента , как мы создали наш проект с помощью django-admin startproject , все модули для аутентификации пользователей были активированы. Они состоят из двух элементов, перечисленных в нашем INSTALLED_APPS in settings.py :

  • django.contrib.auth содержит ядро платформы аутентификации и ее модели по умолчанию.
  • django.contrib.contenttypes – это система типов контента Django, которая позволяет связывать разрешения с моделями, которые вы создаете.

и эти элементы в настройках MIDDLEWARE_CLASSES :

  • Промежуточное программное обеспечение сеанса управляет сеансами между запросами.
  • Промежуточное программное обеспечение аутентификации связывает пользователей с запросами с помощью сеансов.
  • SessionAuthenticationMiddleware выводит пользователей из других сеансов после смены пароля.

С этими настройками на месте, когда мы выполнили команду manage.py миграция мы уже создали необходимые таблицы базы данных для моделей, связанных с проверкой подлинности, и разрешений для любых моделей, определенных в наших установленных приложениях. На самом деле, мы можем увидеть их на сайте администратора, в разделе Пользователи.

Но мы хотим сделать по крайней мере две вещи. Сначала мы хотим потребовать аутентификации для некоторых действий в нашем веб-приложении (например, при добавлении нового обзора wine). Во-вторых, мы хотим, чтобы пользователи могли зарегистрироваться и войти в систему с помощью нашего веб-приложения (а не через сайт администратора).

Ограничение доступа к зарегистрированным пользователям

Теперь давайте признаем, что мы можем просто создавать пользователей с помощью интерфейса администратора. Перейдите туда и создайте пользователя, которого мы будем использовать в этом разделе. Если мы недавно использовали интерфейс администратора, мы, вероятно, продолжим входить в систему как администратор. Пока все в порядке.

Следующее, что мы хотим сделать,-это ограничить доступ к нашему представлению add_review , чтобы его могли использовать только зарегистрированные пользователи.

Чистый и элегантный способ ограничения доступа к представлениям-это использование аннотации @login_required . Измените функцию add_review в reviews/views.py итак, это выглядит так:

@login_required
def add_review(request, wine_id):
    wine = get_object_or_404(Wine, pk=wine_id)
    form = ReviewForm(request.POST)
    if form.is_valid():
        rating = form.cleaned_data['rating']
        comment = form.cleaned_data['comment']
        user_name = form.cleaned_data['user_name']
        user_name = request.user.username
        review = Review()
        review.wine = wine
        review.user_name = user_name
        review.rating = rating
        review.comment = comment
        review.pub_date = datetime.datetime.now()
        review.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse('reviews:wine_detail', args=(wine.id,)))
    
    return render(request, 'reviews/wine_detail.html', {'wine': wine, 'form': form})

Мы сделали две модификации. Первый-добавить аннотацию @login_required . Таким образом, мы разрешаем доступ к этой функции просмотра только зарегистрированным пользователям. Во-вторых, использовать request.user.username в качестве имени пользователя для наших обзоров. Объект запроса имеет ссылку на активного пользователя, и этот экземпляр имеет поле username , которое мы можем использовать по мере необходимости.

Поскольку нам больше не нужно поле имени пользователя в форме, мы можем изменить этот класс формы в reviews/forms.py следующим образом.

class ReviewForm(ModelForm):
    class Meta:
        model = Review
        fields = ['rating', 'comment']
        widgets = {
            'comment': Textarea(attrs={'cols': 40, 'rows': 15}),
        }
введите описание изображения здесь

Если пользователь не вошел в систему, он будет перенаправлен на страницу входа в систему. Вы можете попробовать это, выйдя из системы на странице администратора, а затем попытавшись добавить обзор вина.

Если вы попытаетесь это сделать, вы увидите ошибку Страница не найдена (404) , так как мы не определили сопоставление URL-адреса с запросом страницы входа в систему, а также не определили шаблон для него. Также обратите внимание, что URL-адрес, на который вы перенаправлены, включает в себя next=... параметр, который будет целевой страницей после того, как мы правильно войдем в систему.

Просмотры входа в систему

Django предоставляет несколько представлений, которые можно использовать для управления логином, выходом из системы и паролем. Мы будем использовать их здесь. Так что все по порядку. Измените список urlpatterns в winerama/urls.py и оставьте его следующим образом.

urlpatterns = [
    url(r'^reviews/', include('reviews.urls', namespace="reviews")),
    url(r'^admin/', include(admin.site.urls)),
    url('^accounts/', include('django.contrib.auth.urls'))
]

Мы только что импортировали все сопоставления из django.contrib.auth.url-адреса . Теперь нам нужны шаблоны для различных веб-страниц управления пользователями. Они должны быть помещены в шаблоны/регистрация в корневую папку для нашего проекта Django.

Например, создайте там login.html шаблон со следующим кодом:

{% extends 'base.html' %}
{% load bootstrap3 %}


{% block title %}

Login

{% endblock %} {% block content %}
{% csrf_token %} {% bootstrap_form form layout='inline' %} {% buttons %} {% endbuttons %}
{% endblock %}

Чтобы наши шаблоны были доступны, нам нужно изменить список TEMPLATES в winerama/settings.py чтобы включить эту папку.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
введите описание изображения здесь

Нам нужно создать шаблоны для каждого представления управления пользователями. В этом разделе мы просто приведем два: templates/registration/login.html и ‘templates/registration/logged_out.html”. Мы также переместим reviews/templates/reviews/base.html шаблон к основному templates/base.html папка, чтобы ее можно было использовать по всему проекту. Поэтому нам нужно обновить все директивы шаблона {% extend … % }, которые использовали его.

Проверьте репо GitHub , чтобы узнать, как должны выглядеть html-шаблоны.

Добавление элементов управления сеансом

Следующее, что нам нужно сделать, – это предоставить кнопки входа и выхода в нашем меню. Перейти к templates/base.html и измените элемент в шаблоне, содержащем меню навигации, чтобы он выглядел следующим образом.


Важная часть здесь заключается в том, как мы используем контекстный объект user.is_authenticated в выражении {% if%} , чтобы показать правильные элементы меню. Когда пользователь вошел в систему, мы показываем кнопку выхода из системы и наоборот.

Если бы вы попробовали, вы, вероятно, заметили, что при входе в систему через меню мы получим ошибку 404 при попытке перейти на страницу профиля пользователя. Все в порядке. Мы еще не предоставили страницу профиля пользователя. Мы решим этот вопрос в следующем разделе.

Опять же, эта точка проекта соответствует тегу git stage-1.1 .

Страница Профиля пользователя

На самом деле наш профиль пользователя будет состоять из списка отзывов вошедшего в систему пользователя. Для этого нам понадобится несколько вещей:

  • Нам нужно определить сопоставление по умолчанию для целевой страницы после входа в систему (когда параметр next не указан).
  • Затем нам нужно определить отображение для нового представления, которое мы собираемся добавить.
  • Нам нужно определить функцию просмотра, которая возвращает отзывы, предоставленные пользователем.
  • Нам нужно определить шаблон для отображения результата предыдущего представления.
  • Для этого нам нужно создать пункт меню.

Давайте начнем с определения сопоставления по умолчанию. Это делается на уровне конфигурации проекта. Перейти к winerama/settings.py и добавьте следующую строку.

LOGIN_REDIRECT_URL = '/reviews/review/user'

Теперь нам нужно определить сопоставления в reviews/urls.py как показано в репозитории GitHub на этапе 1.2 (прямо сейчас у нас возникли проблемы с отображением этого фрагмента кода в строке, поэтому вам нужно будет взглянуть на него там, на GitHub).

Там мы указываем два сопоставления. Один используется, когда передается имя пользователя, а другой – когда его нет. Для нового представления требуется функция в reviews/views.py , имена user_review_list как определено в сопоставлении URL-адресов. Добавьте следующее в файл представления.

def user_review_list(request, username=None):
    if not username:
        username = request.user.username
    latest_review_list = Review.objects.filter(user_name=username).order_by('-pub_date')
    context = {'latest_review_list':latest_review_list, 'username':username}
    return render(request, 'reviews/user_review_list.html', context)

Как вы видите, мы просто добавили фильтр к коду, который мы использовали в списке последних обзоров, а затем использовали новое имя шаблона user_review_list.html . Мы могли бы использовать существующий шаблон для review_list.html , но мы хотим изменить название на что-то более специфичное для пользователя. Наконец, мы можем решить, следует ли требовать от пользователей входа в систему для этого представления. Если нет (как мы это сделали), отзывы пользователей являются общедоступными, поэтому пользователи, которые не вошли в систему, также могут их просматривать.

Далее нам нужно создать шаблон следующим образом.

{% extends 'reviews/review_list.html' %}

{% block title %}

Reviews by {{ user.username }}

{% endblock %}

То есть мы расширяем review_list.html шаблон и просто определите {% заголовок блока%} , чтобы заменить заголовок на тот, который включает имя пользователя.

Наконец, давайте добавим пункт меню для нового представления. Нам нужна ссылка с надписью Hello USER_NAME рядом с пунктом меню выход из системы|/. Перейдите и измените элемент в templates/base.html таким образом, это выглядит следующим образом (посмотрите на файл GitHub stage-1.2 , если у вас возникли проблемы с отображением html-тегов ниже).


центр

Наконец, мы хотим иметь возможность переходить на страницы отзывов других пользователей. Например, когда мы видим имя пользователя в обзоре wine, мы хотим иметь возможность щелкнуть его имя и перейти на страницу отзывов пользователей. Это означает, что нам нужно обновить review_list.html и review_detail.html шаблоны и замените текст имени пользователя элементом следующим образом (это reviews_detail.html шаблон).

{% extends 'base.html' %}

{% block title %}

{{ review.wine.name }}

{% endblock %} {% block content %}

Rated {{ review.rating }} of 5 by {{ review.user_name }}

{{ review.pub_date }}

{{ review.comment }}

{% endblock %}

Вы можете перейти в stage-1.2 , чтобы посмотреть, как эти файлы выглядят после обновлений.

И это все. Мы создали правильную целевую страницу пользователя. Он такой же, как и список отзывов, но отфильтрован, чтобы включать только эти отзывы пользователей. Это представление также можно использовать для проверки конкретных отзывов пользователей. Этот пункт проекта соответствует тегу git stage-1.2 .

Страница регистрации

У нас уже есть возможность создавать пользователей, но только через интерфейс администратора (или с помощью кода). Мы хотим, чтобы незарегистрированный пользователь мог зарегистрироваться и создать свою собственную учетную запись пользователя. Мы могли бы создавать формы и представления для этого, но есть очень хорошее приложение для регистрации Django , которое мы можем установить и использовать для этого.

Давайте начнем с установки пакета приложений с помощью нашего pip Anaconda следующим образом. Предположим, что мы находимся в папке, содержащей установку anaconda:

./anaconda/bin/pip install django-registration-redux

Если все пойдет хорошо, нам нужно добавить приложение в список INSTALLED_APPS в winerama/settings.py следующим образом:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'bootstrap3',
    'reviews',
    'registration',
)

Добавьте также следующие значения в файл настроек.

ACCOUNT_ACTIVATION_DAYS = 7 # One-week activation window
REGISTRATION_AUTO_LOGIN = True # Automatically log the user in.

Как только мы это сделаем, нам нужно установить модель, используемую настройкой по умолчанию. Из терминала в корне проекта выполните следующие действия.

python manage.py makemigrations

И затем

pythonmanage.py migrate

Приложение включает в себя различные представления управления пользователями, но мы хотим использовать только регистрационные. Установите следующее в поле winerama/urls.py файл.

urlpatterns = [
    url(r'^reviews/', include('reviews.urls', namespace="reviews")),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^accounts/', include('registration.backends.simple.urls')),
    url(r'^accounts/', include('django.contrib.auth.urls', namespace="auth")),    
]

Нам нужно предоставить два шаблона, которые заменят шаблоны по умолчанию. Мы хотим, чтобы наш сайт больше соответствовал стилю нашего сайта. Они и есть `templates/registration/registration_form.html” и “templates/registration/registration_complete.html”. Первый выглядит так.

{% extends 'base.html' %}
{% load bootstrap3 %}


{% block title %}

Register

{% endblock %} {% block content %}
{% csrf_token %} {% bootstrap_form form layout='inline' %} {% buttons %} {% endbuttons %}
{% endblock %}
введите описание изображения здесь

Там мы просто следуем той же структуре, которую мы использовали для шаблона входа в систему. Ничего особенного. Тот, который для регистрации завершен, выглядит следующим образом.

{% extends 'base.html' %}
{% load bootstrap3 %}


{% block title %}

Register

{% endblock %} {% block content %} Thanks for registering! {% endblock %}
введите описание изображения здесь

Они должны быть названы таким образом и находиться в основной папке templates/registration для django-registration , чтобы найти их.

Мы только что использовали самый простой подход к созданию функции регистрации пользователей. Если вы заинтересованы в более сложном (и готовом к производству) подходе, например, отправке пользователю писем с подтверждением активации/подтверждением или представлениях восстановления/сброса пароля, ознакомьтесь с документами регистрации Django . Основная проблема с их использованием в этом уроке заключается в том, что они связаны с использованием сервера электронной почты, и это не очень связано с тем, чему мы хотим научить здесь.

Эта точка проекта соответствует тегу git stage-2 репо проекта.

Выводы

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

Однако наше управление пользователями было очень наивным и простым. Есть много проблем, которые нам необходимо решить, если мы хотим запустить эту систему в производство, например, обеспечить двухэтапный процесс активации учетных записей пользователей, проверить, использовалась ли ранее электронная почта, или даже разрешить пользователям регистрироваться в своих социальных сетях.

Но того, что мы сделали до сих пор, достаточно для нашей конечной цели-показать, как веб-сайт может включать рекомендательную систему и каков его рабочий процесс при сборе пользовательских данных. Наша конечная цель-построить модели для предоставления рекомендаций. Это будет целью третьей и последней части нашего урока.

Помните, что вы можете следовать учебнику на любом этапе разработки, разветвляя репо в свою учетную запись GitHub, а затем клонируя в свою рабочую область и проверяя соответствующий тег. Разветвляя репо, вы можете изменять его по своему усмотрению и экспериментировать с ним столько, сколько вам нужно. Если в какой-то момент вам захочется немного помочь с каким-то шагом урока или сделать его своим собственным, мы можем провести сеанс 1:1 Codementor об этом.