Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Django
  • » Как правильно спроектировать модели? [RSS Feed]

#1 Март 14, 2013 12:22:30

MikaMika
Зарегистрирован: 2012-11-07
Сообщения: 51
Репутация: +  0  -
Профиль   Отправить e-mail  

Как правильно спроектировать модели?

Привет ребята!
Запутался с проектированием моделей.
Подскажите пожалуйста.
Есть две модели “Транспорт” и “ТипТранспорта”.
Транспорт может быть: машина, лодка, танк, самолёт, поезд, вертолёт, звездолёт, космический корабль и т.д.
Тип транспорта может быть: сухопутный, морской, общий, воздушный.

class ТипТранспорта(models.Model):
    name = models.CharField()
    
    
class Транспорт(models.Model):
    name = models.CharField()    

Так как некоторые виды транспорта (модель - Транспорт) могут иметь несколько типов (модель - ТипТранспорта), то как лучше сделать взаимосвязи между моделями?
Вариант 1:
class ТипТранспорта(models.Model):
    name = models.CharField()
    
    
class Транспорт(models.Model):
    types = models.ManyToManyField(ТипТранспорта)
    name = models.CharField()

Транспорт может иметь несколько типов и у одного типа может быть несколько видов транспорта.

или
Вариант 2:
class ТипТранспорта(models.Model):
    transport = ForeignKey(Транспорт)
    name = models.CharField()
    
    
class Транспорт(models.Model):
    name = models.CharField()

В этом случае если тип транспорта принадлежит нескольким видам транспорта, то придётся вставлять две записи с одинаковым типом которые ссылаются на разный вид транспорта из модели “Транспорт”.

Я плохо понимаю когда лучше использовать ForeingKey, а когда ManyToMany связи.
Первый вариант хороший и как мне кажется правильный, но при выборке из модели Транспорт:
transport = Транспорт.objects.get(transport__name='сухопутный')
я бы хотел получить конкретное значение transport.types, которое равно “Сухопутный”, а не набор записей ManyToMany. Что бы потом спокойно подставлять это значение в шаблоне.
А так мне приходится дополнительно фильтровать transport.types в шаблонах.

Офлайн

#2 Март 14, 2013 13:20:14

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Как правильно спроектировать модели?

ИМХО правильней типы транспорта разделить на несколько структур, вроде такого
Тип_среда : сухопутный, морской, воздушный.
Тип_назначение : гражданский, военный
Тип_перевозка: люди, товары, комбинированный
Тип_привод: ручной, ДВС, атомный, ионный
и т.д. таким образом, чтобы транспорт можно было однозначно идентифицировать только одной сущностью из каждого типа.



Офлайн

#3 Март 14, 2013 20:18:11

MikaMika
Зарегистрирован: 2012-11-07
Сообщения: 51
Репутация: +  0  -
Профиль   Отправить e-mail  

Как правильно спроектировать модели?

FishHook, спасибо.
А если применить нормализацию таблиц:

class ТипТранспорта(models.Model):
    name = models.CharField()
    
    
class Транспорт(models.Model):
    name = models.CharField()
class Вид_и_Тип(models.Model):
    transport = models.ForeingKey(Транспорт)
    ttype = models.ForeingKey(ТипТранспорта)
В модели Вид_и_Тип мы однозначно указываем какому типу какой вид транспорта принадлежит.
Как такой вариант?

Отредактировано MikaMika (Март 14, 2013 20:18:31)

Офлайн

#4 Март 15, 2013 05:24:00

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Как правильно спроектировать модели?

MikaMika
В модели Вид_и_Тип мы однозначно указываем какому типу какой вид транспорта принадлежит.
Как такой вариант?
У Вас же несколько типов может быть, в Вид_и_Тип Вы же не запихаете больше одного типа.



Офлайн

#5 Март 15, 2013 16:09:36

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2763
Репутация: +  185  -
Профиль   Отправить e-mail  

Как правильно спроектировать модели?

>В модели Вид_и_Тип мы однозначно указываем какому типу какой вид транспорта принадлежит.

Отношение многое ко многим автоматически создаёт таблицу связи с подобной структурой.



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

Офлайн

#6 Март 15, 2013 16:32:36

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Как правильно спроектировать модели?

Rodegast
>В модели Вид_и_Тип мы однозначно указываем какому типу какой вид транспорта принадлежит.Отношение многое ко многим автоматически создаёт таблицу связи с подобной структурой.
Я знаю.
Но посмотрите на этот пост, автор уже не хочет ManyToMany и правильно делает.



Отредактировано FishHook (Март 15, 2013 16:33:13)

Офлайн

#7 Март 15, 2013 16:52:52

MikaMika
Зарегистрирован: 2012-11-07
Сообщения: 51
Репутация: +  0  -
Профиль   Отправить e-mail  

Как правильно спроектировать модели?

FishHook
У Вас же несколько типов может быть, в Вид_и_Тип Вы же не запихаете больше одного типа.
Почему нет?
Пример (модель - Вид_и_Тип) :
id тип вид
1 общий автомобиль
2 сухопутный автомобиль
3 сухопутный танк
4 военный танк

Всё это будет ссылаться на другие таблицы с помощью ForeingKey.

Отредактировано MikaMika (Март 15, 2013 16:54:38)

Офлайн

#8 Март 15, 2013 19:51:58

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2763
Репутация: +  185  -
Профиль   Отправить e-mail  

Как правильно спроектировать модели?

> автор уже не хочет ManyToMany и правильно делает.

Судя по третьему посту автор решил сделать собственную реализацию ManyToMany

> Тип транспорта может быть: сухопутный, морской, общий, воздушный.

Должны существовать классификаторы видов транспорных средств кторорые позволяют однозначно охарактеризовать конкретный транспорт. Их используй и тогда ManyToMany не понадобиться.



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

Офлайн

#9 Март 16, 2013 06:47:20

MikaMika
Зарегистрирован: 2012-11-07
Сообщения: 51
Репутация: +  0  -
Профиль   Отправить e-mail  

Как правильно спроектировать модели?

Rodegast, в некоторых случаях использовать классификаторы бывает тяжело.
Например гороскоп.
Знак зодиака крыса может относится к японскому и китайскому гороскопу, а у этих гороскопов может быть сколько угодно знаков зодиака.
Связь ManyToMany.
Есть модель с типами гороскопов:

class HType(models.Model):
    name = models.CharField()
Элементы в модели:
китайский
японский
зодиакальный
# ………………
Даже если классифицировать модели, например так:
# зодиакальный
class HType_Other(models.Model):
    name = models.CharField()
# китайский
# японский
class HType_Asian(models.Model):
    name = models.CharField()
всё равно две записи типа (японский и китайский гороскоп) буду ссылаться на множетсво знаков зодиака.
Как ещё можно классифицировать данные в модели HType_Asian?
И не приведёт ли это к излишней нормализации, а в следствие чего, к излишнем запросам в БД?

Отредактировано MikaMika (Март 16, 2013 07:04:24)

Офлайн

#10 Март 16, 2013 18:28:14

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2763
Репутация: +  185  -
Профиль   Отправить e-mail  

Как правильно спроектировать модели?

Если тебе на гороскопах понятней, то на них и объясняю:
Создаёшь 2 модели:
1) Astrolog (китайский, японский, вуду, ….)
2) Znak (Козерог, Крыса, Собака, Таракан, ….)
Вторую модель связываешь по внешнему ключу с первой и всё. Если у тебя крыса может быть японской и китайской, то во второй модели будут 2 записи одна для японцев другая для китайцев.



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

Офлайн

  • Начало
  • » Django
  • » Как правильно спроектировать модели?[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version