Язык программирования Python

Создание блога на Django. Часть 2: Модели

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

User

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

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

python manage.py startapp users
Code language: CSS (css)

Это создаст следующую структуру файлов в нашем проекте:

users/ __init__.py admin.py apps.py migrations/ __init__.py models.py tests.py views.py

Помимо этих файлов в корне создается файл db.sqlite3. Это связано с тем, что по умолчанию в файле simple_blog/settings.py мы настроили базу данных sqlite, но для работы я бы рекомендовал вам использовать любой из других вариантов, которые поддерживает django, например, postgresql, mysql и oracle.

Далее перейдем к самому главному. В файл users/models.py мы добавим следующие строки:

"""Users models.""" # Django from django.contrib.auth.models import User from django.db import models class Profile(models.Model): """Profile model. Proxy model that extends the base data with other information. """ user = models.OneToOneField(User, on_delete=models.PROTECT) website = models.URLField(max_length=200, blank=True) photo = models.ImageField( upload_to='users/pictures', blank=True, null=True ) date_modified = models.DateTimeField(auto_now=True) def __str__(self): """Return username.""" return self.user.username

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

Следующее, что мы сделаем в классе Profile, это свяжем класс User с нашим классом one to one и добавим опцию on_delete=models.PROTECT, которая не позволит удалять пользователей, так как у нас есть возможность их отключать. Учитывая, что пользователи связаны с несколькими таблицами, их удаление может привести к удалению важной информации, связанной с ними.

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

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

Post

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

python manage.py startapp posts python manage.py startapp categories python manage.py startapp comments
Code language: CSS (css)

Добавим следующий код в posts/models.py:

"""Posts models.""" # Django from django.db import models from django.utils.text import slugify from django.contrib.auth.models import User from ckeditor.fields import RichTextField from categories.models import Category class Post(models.Model): """Post model.""" user = models.ForeignKey(User, on_delete=models.PROTECT) profile = models.ForeignKey('users.Profile', on_delete=models.PROTECT) title = models.CharField(max_length=255) image_header = models.ImageField(upload_to='posts/photos') post = RichTextField() created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) is_draft = models.BooleanField(default=True) url = models.SlugField(max_length=255, unique=True) views = models.PositiveIntegerField(default=0) categories = models.ManyToManyField(Category) class Meta: ordering = ('title',) def __str__(self): """Return title and username.""" return '{} by @{}'.format(self.title, self.user.username) def save(self, *args, **kwargs): self.url = slugify(self.title) super(Post, self).save(*args, **kwargs)

Для этой модели мы импортируем slugify для создания ЧПУ, класс User (так как пост будет создаваться пользователем), и тип данных RichTextField, который является полем, взятым из библиотеки, импортированной в первой части.

Далее мы создадим класс Post и свяжем пользователей с постами с помощью функции ForeignKey. Это будет отношение 1 к N, поскольку пользователь может создать несколько постов, а пост принадлежит одному пользователю. Как и в модели пользователя, мы будем использовать PROTECT, поскольку не хотим потерять записи.

Другие поля:

  • title: Тип поля CharField с максимальным размером 255 символов.
  • image_header: Это будет заголовок нашего поста, который мы сохраним в media/posts/photos.
  • post: Это поле будет типа RichTextField, что позволит нам создавать тексты с различными размерами, шрифтами, цветами и т.д.
  • date_created: Дата создания. Текущая дата будет сохранена по умолчанию атрибутом auto_now_add.
  • date_modified: Дата изменения. Текущая дата будет сохраняться по умолчанию при каждом обновлении поста с помощью атрибута auto_now.
  • is_draft: Булево поле, мы будем сохранять, если статья является черновиком или мы хотим опубликовать ее на сайте.
  • url: Типа slugField, здесь мы будем хранить url, он будет создан из заголовка.
  • views: Количество просмотров.
  • categories: Список категорий, присваиваемых посту, это отношение типа N к N, так как пост может иметь несколько категорий, а категория может принадлежать нескольким постам.

Затем мы объявляем класс Meta и добавляем параметр order by title, это будет означать, что когда мы возвращаем список объектов типа post, по умолчанию он будет сортироваться по записям.

Метод __str__, о котором мы рассказывали ранее.

Метод save. Здесь мы делаем следующее: когда мы собираемся сохранить пост, мы передаем функцию slugify для заголовка и сохраняем его в поле url.

Categories

Он будет очень простым, в нем будет только поле имени. Добавим следующий код:

"""Categories""" from django.db import models # Models # Create your models here. class Category(models.Model): """Category model.""" name = models.CharField(max_length=100,unique=True) class Meta: ordering = ('name',) def __str__(self): return self.name

Comments

В конце мы создадим шаблон для комментариев, он будет содержать следующий код:

"""Comments""" from django.db import models from django.contrib.auth.models import User from posts.models import Post # Model # Create your models here. class Comment(models.Model): """Comment model.""" user = models.ForeignKey(User, on_delete=models.PROTECT) profile = models.ForeignKey('users.Profile', on_delete=models.PROTECT) post = models.ForeignKey(Post, on_delete=models.PROTECT) comment = models.CharField(max_length=5000) def __str__(self): return self.comment

Здесь мы добавили отношения к пользователю и посту, которые будут от 1 до N для обоих случаев, поскольку комментарий принадлежит пользователю и посту, а пользователь и пост могут иметь несколько комментариев. Внешний ключ, который связывает комментарии с постом в модели поста, делает так, что каждый раз, когда мы получаем объект типа post, мы получаем все комментарии к этому посту. Если у нас много комментариев, это может замедлить работу сайта, а так мы получаем комментарии только тогда, когда они нам нужны.

Теперь нам нужно отредактировать наш файл simple_blog/settings.py и добавить в него следующие модули:

INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # Rich text editor 'ckeditor', # Local apps 'posts', 'users', 'categories', 'comments', ]
Code language: PHP (php)

После создания моделей запускаем следующую команду:

python manage.py makemigrations python manage.py migrate
Code language: CSS (css)

Первый генерирует файл для создания/изменения таблицы, а второй создаст таблицы в базе данных.

Заключение

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

В следующей части мы займемся административной частью блога.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *