Книга «Изучаем Python»



Pdf көрінісі
бет236/238
Дата07.01.2022
өлшемі7,86 Mb.
#18670
түріКнига
1   ...   230   231   232   233   234   235   236   237   238
ПРИМЕЧАНИЕ

Вместо миграции можно просто сбросить содержимое базы данных, но это приведет к потере всех 

существующих данных . Полезно научиться выполнять миграцию базы данных без нарушения це-

лостности данных пользователей . Если вы хотите начать с новой базы данных, используйте ко-

манду python manage .py flush для повторного построения структуры базы данных . Вам придется 

создать нового суперпользователя, а все данные будут потеряны .

Ограничение доступа к темам

В настоящее время пользователь, выполнивший вход, будет видеть все темы не-

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

ложение, чтобы каждый пользователь видел только принадлежащие ему темы.

Внесите следующее изменение в функцию 

topics()

 в файле 

views .py

:

views.py

...

@login_required




Редактирование данных    433

def topics(request):

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

    topics = Topic.objects.filter(owner=request.user).order_by('date_added')

context = {'topics': topics}

return render(request, 'learning_logs/topics.html', context)

...

Если пользователь выполнил вход, в объекте запроса устанавливается атрибут 



request.user

 с информацией о пользователе. Фрагмент кода 

Topic.objects.

filter(owner=request.user)

 приказывает Django извлечь из базы данных только 

те объекты 

Topic

, у которых атрибут 



owner

 соответствует текущему пользователю. 

Так как способ отображения не изменяется, изменять шаблон для страницы тем 

вообще не нужно.

Чтобы увидеть, как работает этот способ, выполните вход в качестве пользователя, 

с которым связаны все существующие темы, и перейдите к странице со списком 

тем. На ней должны отображаться все темы. Теперь завершите сеанс и войдите 

снова с другой учетной записью. На этот раз страница должна быть пустой.

Защита тем пользователя

Никаких реальных ограничений на доступ к страницам еще не существует, по-

этому любой зарегистрированный пользователь может опробовать разные URL 

(например, http://localhost:8000/topics/1/) и просмотреть страницы тем, которые 

ему удастся подобрать.

Попробуйте сделать это. После входа с учетной записью суперпользователя ско-

пируйте URL или запишите идентификатор в URL темы, после чего завершите 

сеанс и войдите снова от имени другого пользователя. Введите URL этой темы. 

Вам удастся прочитать все записи, хотя сейчас вы вошли под именем другого 

пользователя.

Чтобы решить эту проблему, мы будем выполнять проверку перед получением 

запрошенных данных в функции представления 

topic()

:

views.py

from django.shortcuts import render

from django.http import HttpResponseRedirect, Http404



from django.core.urlresolvers import reverse

...


@login_required

def topic(request, topic_id):

"""Выводит одну тему и все ее записи."""

topic = Topic.objects.get(id=topic_id)

    # Проверка того, что тема принадлежит текущему пользователю.

    if topic.owner != request.user:



        raise Http404

        


entries = topic.entry_set.order_by('-date_added')

context = {'topic': topic, 'entries': entries}

return render(request, 'learning_logs/topic.html', context)

...



434    Глава 19  •  Учетные записи пользователей

Код 404 — стандартное сообщение об ошибке, которое возвращается в тех случаях, 

когда запрошенный ресурс не существует на сервере. В данном случае мы импор-

тируем исключение 

Http404

 , которое будет выдаваться программой при запросе 

пользователем темы, которую ему видеть не положено. Получив запрос темы, перед 

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

текущим пользователем приложения. Если тема не принадлежит текущему пользова-

телю, выдается исключение 

Http404

 , а Django возвращает страницу с ошибкой 404.

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

сообщение «Страница не найдена». В главе 20 проект будет настроен так, чтобы 

пользователь видел полноценную страницу ошибки.

Защита страницы edit_entry

Страницы 

edit_entry

 используют URL-адреса в форме http://localhost:8000/edit_

entry/entry_id/, где entry_id — число. Защитим эту страницу, чтобы никто не мог 

подобрать URL для получения доступа к чужим записям:



views.py

...


@login_required

def edit_entry(request, entry_id):

"""Редактирует существующую запись."""

entry = Entry.objects.get(id=entry_id)

topic = entry.topic

    if topic.owner != request.user:

        raise Http404

if request.method != 'POST':

# Исходный запрос; форма заполняется данными текущей записи.

...


Программа читает запись и тему, связанную с этой записью. Затем мы проверяем, 

совпадает ли владелец темы с текущим пользователем; при несовпадении выдается 

исключение 

Http404


.

Связывание новых тем с текущим пользователем

В настоящее время страница добавления новых тем несовершенна, потому что она 

не связывает новые темы с конкретным пользователем. При попытке добавить 

новую тему выдается сообщение об ошибке 

IntegrityError

 с уточнением 

learning_

logs_topic.user_id

 

may



 

not


 

be

 



NULL

. Django говорит, что при создании новой темы 

обязательно должно быть задано значение поля 

owner


.

Проблема легко решается, потому что мы можем получить доступ к информации 

текущего пользователя через объект 

request


. Добавьте следующий код, связыва-

ющий новую тему с текущим пользователем:



views.py

...



Итоги    435

@login_required

def new_topic(request):

"""Определяет новую тему."""

if request.method != 'POST':

# Данные не отправлялись; создается пустая форма.

form = TopicForm()

else:


# Отправлены данные POST; обработать данные.

form = TopicForm(request.POST)

if form.is_valid():

            new_topic = form.save(commit=False)



            new_topic.owner = request.user

            new_topic.save()



return HttpResponseRedirect(reverse('learning_logs:topics'))

            

context = {'form': form}

return render(request, 'learning_logs/new_topic.html', context)

...

При первом вызове 



form.save()

 передается аргумент 

commit=False

, потому что 

новая тема должна быть изменена перед сохранением в базе данных . Атрибуту 

owner


 новой темы присваивается текущий пользователь . Наконец, мы вызываем 

save()


 для только что определенного экземпляра темы . Теперь тема содержит 

все обязательные данные, и ее сохранение пройдет успешно.

Вы сможете добавить сколько угодно новых тем для любого количества разных 

пользователей. Каждому пользователю будут доступны только его собственные 

данные, какие бы операции он ни пытался выполнять: просмотр данных, ввод 

 новых или изменение существующих данных.





Достарыңызбен бөлісу:
1   ...   230   231   232   233   234   235   236   237   238




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет