Django позволяет легко ограничить доступ к определенным страницам для пользователей, выполнивших вход, с помощью декоратора @login_required. Декоратор (decorator) представляет собой директиву, размещенную непосредственно перед определением функции, применяемую к функции перед ее выполнением и влияющую на поведение кода. Рассмотрим пример.

<p>Ограничение доступа к страницам тем</p>

Каждая тема будет принадлежать пользователю, поэтому только зарегистрированные пользователи смогут запрашивать страницы тем. Добавьте следующий код в learning_logs/views.py:

views.py

...

from django.core.urlresolvers import reverse

from django.contrib.auth.decorators import login_required

from .models import Topic, Entry

...

@login_required

def topics(request):

"""Выводит все темы."""

...

Сначала импортируется функция login_required(). Мы применяем login_required() как декоратор для функции представления topics(), для чего перед именем login_required() ставится знак @; он сообщает Python, что этот код должен выполняться перед кодом topics().

Код login_required() проверяет, выполнил ли пользователь вход, и Django выполняет код topics() только при выполнении этого условия. Если же пользователь не выполнил вход, он перенаправляется на страницу входа.

Чтобы перенаправление работало, необходимо внести изменения settings.py и сообщить Django, где искать страницу входа. Добавьте следующий фрагмент в самый конец settings.py:

settings.py

"""

Django settings for learning_log project

...

# Мои настройки

LOGIN_URL = '/users/login/'

Когда пользователь, не прошедший проверку, запрашивает страницу, защищенную декоратором @login_required, Django отправляет пользователя на URL-адрес, определяемый LOGIN_URL в settings.py.

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

<p>Ограничение доступа в Learning Log</p>

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

В приложении Learning Log мы оставим неограниченный доступ к домашней странице, странице регистрации и выхода. Доступ ко всем остальным страницам будет ограничен.

Вот как выглядит файл learning_logs/views.py с декораторами @login_required, примененными к каждому представлению, кроме index():

views.py

...

@login_required

def topics(request):

. ....

@login_required

def topic(request, topic_id):

. ....

@login_required

def new_topic(request):

. ....

. .

@login_required

def new_entry(request, topic_id):

. ....

@login_required

def edit_entry(request, entry_id):

. ....

Попробуйте обратиться к любой из этих страниц без выполнения входа: вы будете перенаправлены обратно на страницу входа. Кроме того, вы не сможете щелкать на ссылках на такие страницы, как new_topic. Но если ввести URL http://localhost:8000/new_topic/, вы будете перенаправлены на страницу входа. Ограничьте доступ ко всем ­URL-адресам, связанным с личными данными пользователей.

<p>Связывание данных с конкретными пользователями</p>

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

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

<p>Изменение модели Topic</p>

В файле models.py изменяются всего две строки:

models.py

from django.db import models

from django.contrib.auth.models import User

class Topic(models.Model):

"""Тема, которую изучает пользователь"""

text = models.CharField(max_length=200)

date_added = models.DateTimeField(auto_now_add=True)

. .owner = models.ForeignKey(User)

def __str__(self):

"""Возвращает строковое представление модели."""

return self.text

class Entry(models.Model):

...

Сначала модель User импортируется из django.contrib.auth. Затем в Topic добавляется поле owner, используемое в отношении внешнего ключа с моделью User.

<p>Идентификация существующих пользователей</p>
Перейти на страницу:

Все книги серии Библиотека программиста

Похожие книги