Найти - Пользователи
Полная версия: Как правильно спроектировать модели?
Начало » Django » Как правильно спроектировать модели?
1
MikaMika
Привет ребята!
Запутался с проектированием моделей.
Подскажите пожалуйста.
Есть две модели “Транспорт” и “ТипТранспорта”.
Транспорт может быть: машина, лодка, танк, самолёт, поезд, вертолёт, звездолёт, космический корабль и т.д.
Тип транспорта может быть: сухопутный, морской, общий, воздушный.
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 в шаблонах.

FishHook
ИМХО правильней типы транспорта разделить на несколько структур, вроде такого
Тип_среда : сухопутный, морской, воздушный.
Тип_назначение : гражданский, военный
Тип_перевозка: люди, товары, комбинированный
Тип_привод: ручной, ДВС, атомный, ионный
и т.д. таким образом, чтобы транспорт можно было однозначно идентифицировать только одной сущностью из каждого типа.
MikaMika
FishHook, спасибо.
А если применить нормализацию таблиц:
class ТипТранспорта(models.Model):
    name = models.CharField()
    
    
class Транспорт(models.Model):
    name = models.CharField()
class Вид_и_Тип(models.Model):
    transport = models.ForeingKey(Транспорт)
    ttype = models.ForeingKey(ТипТранспорта)
В модели Вид_и_Тип мы однозначно указываем какому типу какой вид транспорта принадлежит.
Как такой вариант?

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

Отношение многое ко многим автоматически создаёт таблицу связи с подобной структурой.
FishHook
Rodegast
>В модели Вид_и_Тип мы однозначно указываем какому типу какой вид транспорта принадлежит.Отношение многое ко многим автоматически создаёт таблицу связи с подобной структурой.
Я знаю.
Но посмотрите на этот пост, автор уже не хочет ManyToMany и правильно делает.
MikaMika
FishHook
У Вас же несколько типов может быть, в Вид_и_Тип Вы же не запихаете больше одного типа.
Почему нет?
Пример (модель - Вид_и_Тип) :
id тип вид
1 общий автомобиль
2 сухопутный автомобиль
3 сухопутный танк
4 военный танк

Всё это будет ссылаться на другие таблицы с помощью ForeingKey.
Rodegast
> автор уже не хочет ManyToMany и правильно делает.

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

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

Должны существовать классификаторы видов транспорных средств кторорые позволяют однозначно охарактеризовать конкретный транспорт. Их используй и тогда ManyToMany не понадобиться.
MikaMika
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?
И не приведёт ли это к излишней нормализации, а в следствие чего, к излишнем запросам в БД?
Rodegast
Если тебе на гороскопах понятней, то на них и объясняю:
Создаёшь 2 модели:
1) Astrolog (китайский, японский, вуду, ….)
2) Znak (Козерог, Крыса, Собака, Таракан, ….)
Вторую модель связываешь по внешнему ключу с первой и всё. Если у тебя крыса может быть японской и китайской, то во второй модели будут 2 записи одна для японцев другая для китайцев.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB