Связи между моделями.

В нашем проекте есть одна модель под названием “Объявления”. В этой статье мы создадим новый класс модели “Rubric”, которая будет представлять рубрики объявлений. Допишем в модуль models.py пакета приложения “btest”:

class Rubric(models.Model):
  name = models.CharField(max_length=20, db_index=True,
  verbose_name='Название')
  
  class Meta:
    verbose_name_plural = 'Рубрики'
    verbose_name = 'Рубрика'
    ordering = ['name']

Новая модель содержит одно объявленное поле “name”, которое будет хранить название рубрики. Для этого поля мы сразу велели создать индекс, т.к. будем выводить перечень рубрик отсортированным по их названиям.

Осталось добавить в модель Bb поле внешнего ключа, устанавливающее связь между текущей записью этой модели и записью модели Rubric, т.е. между объявлением и рубрикой, к которой оно относится.

Таким образом будет создана связь “один-со-многими”, при которой одна запись модели Rubric будет связана с произвольным количеством записей модели Bb.

Создадим в последней такое поле, назвав его rubric. Изменим код класса Bb:

class Bb(models.Model):
  title = models.CharField(max_length=50, verbose_name='Товар')
  content = models.TextField(null=True, blank=True, verbose_name='Описание')
  price = models.FloatField(null=True, blank=True, verbose_name='Цена')
  published = models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='Опубликовано')
  rubric = models.ForeignKey('Rubric', null=True,
  on_delete=models.PROTECT, verbose_name='Рубрика')
  
  class Meta:
    verbose_name_plural = 'Объявления'
    verbose_name = 'Объявление'
    ordering = ['-published']

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

  • ссылки на класс – если код, объявляющий класс первичной модели, располагается перед кодом класса вторичной модели;
  • строки с именем класса – если вторичная модель объявлена раньше первичной.

Все поля, создаваемые в моделях, по умолчанию обязательны к заполнению. Следовательно, добавить новое, обязательное к заполнению поле в модель, которая уже содержит записи, нельзя – сама СУБД откажется делать это и выведет сообщение об ошибке.

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

Именованный параметр on_delete управляет каскадными удалениями записей вторичной модели после удаления записи первичной модели, с которой они были связаны. Значение PROTECT этого параметра запрещает каскадные удаления.

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

manage.py makemigrations btest

После выполнения данной команды в папке migrations будет создан модуль миграции с именем вида “002_auto_отметка текущей даты и времени.py”. Выполним созданную миграцию:

manage.py migrate

Зарегистрируем новую модель на административном сайте, добавив в модуль admin.py пакета приложения такие два выражения:

from .models import Rubric
...
admin.site.register(Rubric)

Сохраним файл, запустим отладочный web-сервер и зайдем на административный сайт:


Связи между моделями.

Добавим новую рубрику:


Связи между моделями.


Связи между моделями.

Строковое представление модели

Наша рубрика создалась, но она представляется строкой вида “имя класса модели object значение ключа записи”. Необходимо переопределить в классе модели метод __str__(), возвращающий строковое представление класса.

Откроем модуль models.py и изменим в объявление класса модели Rubric код:

class Rubric(models.Model):
  name = models.CharField(max_length=20, db_index=True,
  verbose_name='Название')
  def __str__(self):
    return self.name
  
  class Meta:
    verbose_name_plural = 'Рубрики'
    verbose_name = 'Рубрика'
    ordering = ['name']

Сохраните файл, обновим страницу списка рубрик и посмотрим, что у нас получилось:


Связи между моделями.

Создадим необходимые рубрики и добавим во все наши объявления соответствующую рубрику:


Связи между моделями.

Осталось сделать так, чтобы в списке записей модели Bb, выводились рубрики объявлений. Для этого необходимо в последовательность имен полей, присвоенную атрибуту list_display класса BbAdmin, поле rubric (в файле admin.py):

list_display = ('title', 'content', 'price', 'published', 'rubric')

Сохраним файл и обновим страницу списка объявлений – и увидим новый столбец:


Связи между моделями.

 
Поделиться в facebook
Facebook
Поделиться в twitter
Twitter
Поделиться в vk
VK
Поделиться в google
Google+
Поделиться в email
Email

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

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

Группа в VK

Помощь проекту

Обнаружили опечатку?

Сообщите нам об этом, выделите текст с ошибкой и нажмите Ctrl+Enter, будем очень признательны!

Свежие статьи

Похожие статьи

Параметры полей и моделей.

Параметры полей и моделей.

Для того, чтобы наша административная панель Django выглядела более понятна для обычного пользователя необходимо указать правильные названия полей. Наша созданная модель представляется непонятной аббревиатурой “Bbs”,

 
Административный web-сайт Django.

Административный web-сайт Django.

Административный web-сайт предоставляет доступ ко всем моделям, объявленным во всех приложениях, что составляют проект. С помощью данной панели можно просматривать, добавлять, править и удалять записи,

 
Создание и использование шаблонов в Django.

Создание и использование шаблонов в Django.

Шаблоны (template) отвечают за формирование внешнего вида приложения. Они предоставляют специальный синтаксис, который позволяет внедрять данные в код HTML. Подсистема Django, называется шаблонизатором, загружает шаблон,

 
Модели и миграции в Django.

Модели и миграции в Django.

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

 

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: