Как лучше всего использовать несколько полей в нескольких моделях? - PullRequest
1 голос
/ 19 июня 2019

Скажем, у меня есть эти модели и поля:

class User(AbstractBaseUser):
    name_title
    name_first
    name_middle_initial
    name_last

    address_1
    address_2
    address_city
    address_state
    address_post_code

class Order(models.Model):
    name_title
    name_first
    name_middle_initial
    name_last

    address_1
    address_2
    address_city
    address_state
    address_post_code

class Shipment(models.Model):
    address_1
    address_2
    address_city
    address_state
    address_post_code

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

Я хочу, чтобы все повторяющиеся поля были идентичны - иметь одинаковое verbose_name, валидации, max_length и т. д.

I 'мы пытались использовать смешанный подход:

class AddressFieldsMixin(models.Model):
    address_1
    address_2
    address_city
    address_state
    address_post_code

class NameFieldsMixin(models.Model):
    name_title
    name_first
    name_middle_initial
    name_last

class User(AbstractBaseUser, AddressFieldsMixin, NameFieldsMixin):
    pass

class Order(models.Model, AddressFieldsMixin, NameFieldsMixin):
    pass

class Shipment(models.Model, AddressFieldsMixin):
    pass

... но это приводит к коллизиям модели / наследования, если мои Mixin классы наследуются от models.Model, и ошибкам "неизвестного поля", если они этого не делают.

Как правильно использовать поля «имя» и «адрес» в нескольких моделях? Спасибо!

1 Ответ

1 голос
/ 19 июня 2019

Вы должны сделать свои модели abstract = True [Django-doc] . Как:

class AddressFieldsModel(models.Model):
    address_1 = ...
    address_2 = ...
    address_city = ...
    address_state = ...
    address_post_code = ...

    class <b>Meta</b>:
        <b>abstract = True</b>

class NameFieldsModel(models.Model):
    name_title = ...
    name_first = ...
    name_middle_initial = ...
    name_last = ...

    class <b>Meta</b>:
        <b>abstract = True</b>

class User(AddressFieldsModel, NameFieldsModel, AbstractBaseUser):
    pass

class Order(AddressFieldsModel, NameFieldsModel, models.Model):
    pass

class Shipment(AddressFieldsModel, models.Model):
    pass

Поскольку эти модели также наследуются от models.Model, это не mixins [wiki] , или, по крайней мере, не в очень строгом определении. Кроме того, вы должны поместить эти классы первыми, поскольку они наследуются от models.Model, и если вы укажете models.Model в качестве первого предка, это приведет к конфликту MRO.

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

Абстрактные базовые классы полезны, когда вы хотите поместить некоторую общую информацию в ряд других моделей . Вы пишете свой базовый класс и ставите abstract=True в Meta классе . Эта модель не будет использоваться для создания таблицы базы данных. Вместо этого, когда он используется в качестве базового класса для других моделей, его поля будут добавлены к полям дочернего класса.

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