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



Pdf көрінісі
бет235/238
Дата07.01.2022
өлшемі7,86 Mb.
#18670
түріКнига
1   ...   230   231   232   233   234   235   236   237   238
Байланысты:
2 5343781172763690906

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):

    ...



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

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

направлены обратно на страницу входа. Кроме того, вы не сможете щелкать на ссылках 

на такие страницы, как 

new_topic

. Но если ввести URL http://localhost:8000/new_topic/

вы будете перенаправлены на страницу входа. Ограничьте доступ ко всем  URL-адресам, 

связанным с личными данными пользователей.

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

Теперь данные, отправленные пользователем, необходимо связать с тем пользо-

вателем, который их отправил. Связь достаточно установить только с данными, 

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

за ними автоматически. Например, в приложении Learning Log на высшем уровне 

находятся темы, а каждая запись связывается с некоторой темой. Если каждая тема 

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

записи в базе данных.

Изменим модель 

Topic


 и добавим отношение внешнего ключа с пользователем. 

После этого необходимо провести миграцию базы данных. Наконец, необходимо 

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

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

Изменение модели Topic

В файле 


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


.

Идентификация существующих пользователей

При проведении миграции Django модифицирует базу данных, чтобы в ней хра-

нилась связь между каждой темой и пользователем. Для выполнения миграции 

Django необходимо знать, с каким пользователем должна быть связана каждая 

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




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

зователем, например суперпользователем. Но для этого сначала необходимо узнать 

идентификатор этого пользователя.

Просмотрим идентификаторы всех пользователей, созданных до настоящего мо-

мента. Запустите сеанс оболочки Django и введите следующие команды:

(venv)learning_log$ python manage.py shell

>>> from django.contrib.auth.models import User



>>> User.objects.all()

[, , ]

>>> for user in User.objects.all():



...     print(user.username, user.id)

... 


ll_admin 1 

eric 2 


willie 3 

>>>


В точке  в сеанс оболочки импортируется модель 

User


. После этого просматрива-

ются все пользователи, созданные до настоящего момента . В выходных данных 

перечислены три пользователя: ll_admineric и willie.

В точке  перебирается список пользователей, и для каждого пользователя вы-

водится его имя и идентификатор. Когда Django спросит, с каким пользователем 

связать существующие темы, мы используем один из этих идентификаторов.

Миграция базы данных

Зная значение идентификатора, можно провести миграцию базы данных.

(venv)learning_log$ python manage.py makemigrations learning_logs



You are trying to add a non-nullable field 'owner' to topic without a default;

we can't do that (the database needs something to populate existing rows).

Please select a fix:



 1) Provide a one-off default now (will be set on all existing rows)

 2) Quit, and let me add a default in models.py

Select an option: 1



Please enter the default value now, as valid Python

The datetime and django.utils.timezone modules are available, so you can do 

e.g. timezone.now()

>>> 1


Migrations for 'learning_logs':

  0003_topic_owner.py:

    - Add field owner to topic

Сначала выдается команда 

makemigrations

 . В ее выходных данных  Django со-

общает, что мы пытаемся добавить обязательное поле (значения которого отличны 

от null) в существующую модель (

topic

) без указания значения по умолчанию. 



Django предоставляет два варианта : мы можем либо указать значение по умол-

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

по умолчанию в 

models .py

. В точке  выбирается первый вариант. Тогда Django 

запрашивает значение по умолчанию .

Чтобы связать все существующие темы с исходным административным пользо-

вателем 


ll_admin

, я ввел в точке 

 идентификатор пользователя 1. Вы можете 




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

использовать идентификатор любого из созданных пользователей; он не обязан 

быть суперпользователем. Django проводит миграцию базы данных, используя это 

значение, и создает файл миграции 

0003_topic_owner .py

, добавляющий поле 

owner

 

в модель 



Topic

.

Теперь можно провести миграцию. Введите следующую команду в активной вир-



туальной среде:

(venv)learning_log$ python manage.py migrate

Operations to perform:

  Synchronize unmigrated apps: messages, staticfiles

  Apply all migrations: learning_logs, contenttypes, sessions, admin, auth

...


Running migrations:

  Rendering model states... DONE

  Applying learning_logs.0003_topic_owner... 



OK

(venv)learning_log$

Django применяет новую миграцию с результатом 

OK

 . Чтобы убедиться в том, что 



миграция сработала так, как и ожидалось, можно воспользоваться интерактивной 

оболочкой:

  >>> from learning_logs.models import Topic



>>> for topic in Topic.objects.all():

...     print(topic, topic.owner)

... 


Chess ll_admin 

Rock Climbing ll_admin 

>>>

После импортирования 



Topic

 из 


learning_logs.models

  мы перебираем все су-

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

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

ll_admin

.



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




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

    Басты бет