Управление наследованием в Джанго - PullRequest
0 голосов
/ 11 октября 2018

Итак, в нашей базе данных у нас была модель автомобиля, но могли быть разные типы автомобилей, с различными полями и разными процессами, связанными с ними, поэтому я создал несколько классов моделей, которые наследуются от этой машины, это что-то вроде этого:

class Car(models.Model):
    field = models.CharField(max_length=300)


class CarA(Car):
    field_a = models.CharField(max_length=300)


class CarA1(CarA):
    field_a1 = models.CharField(max_length=300)


class CarA2(CarA):
    field_a2 = models.CharField(max_length=300)


class CarB(Car):
    field_b = models.CharField(max_length=300)

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

class Trip(BaseModel):
    car = models.ForeignKey(Car)

Если у меня есть экземпляр CarA1, car_a1, я могу сохранить его вПоездка с car_a1.car_ptr, но она будет сохранена как Автомобиль, и оттуда я не думаю, что есть способ получить экземпляр CarA1 снова, кроме поиска по идентификатору автомобиля во всех подклассах.

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

Что вы предлагаете сделать?Я могу оставить только класс Car с определенными полями nullable (field_a, field_b и т. Д.) И полем для указания типа автомобиля, но это кажется неправильным, мне придется проверить тип для проверкиполя и т. д. Но сейчас это кажется лучшим решением.

Я использую Django 1.11 и Python 3.6, кстати.

Извините, я не использовал реальный код, я думал, что это будетбыть более сложным, также извините, если я не объяснил это очень хорошо, я лишен сна и стресса.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Во-первых, вы можете получить дочернюю модель из родительской модели (см. наследование на основе модели ).

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

class Car(models.Model):
    CAR_A = 'car_a'
    CAR_B = 'car_b'
    CAR_TYPE_CHOICES = (
        (CAR_A, 'Car_A'),
        (CAR_B, 'Car_b'),
    )
    field = models.CharField(max_length=300)
    car_type = models.CharField(max_length=20, choices=CAR_TYPE_CHOICES)

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

class CarA(Car):
    field_a = models.CharField(max_length=300)

    def save(self, *args, **kwargs):
        self.car_type = Car.CAR_A
        super(CarA, self).save(*args, **kwargs)

# ... similarly for CarB

ТеперьВы можете перейти к дочерней модели с Car на основе ее car_type.

if car.car_type === Car.CAR_A:
    print(car.cara.field_a) 

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

0 голосов
/ 11 октября 2018

Проблема в вашей модели состоит в том, что когда появился новый тип автомобиля, скажем, автомобиль c, вам нужно создать для этого еще одну таблицу.Это не идеально, и вам нужна одна таблица для хранения сведений об автомобиле (обычно используемая) и отдельная таблица с надписью «Свойства» для хранения других сведений и связи внешнего ключа с моделью автомобиля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...