【问题标题】:How best to use multiple fields across multiple models?如何最好地跨多个模型使用多个字段?
【发布时间】:2019-06-20 02:43:55
【问题描述】:

假设我有这些模型和字段:

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、validations、max_length 等。

我尝试过采用 mixin 方法:

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,则会导致模型/继承冲突,如果不继承,则会出现“未知字段”错误。

在多个模型中重复使用“名称”字段和“地址”字段的正确方法是什么?谢谢!

【问题讨论】:

  • 你应该把 mixins(从技术上讲,这些不是 mixins)放在继承的首位。

标签: python django


【解决方案1】:

你应该让你的模型abstract = True [Django-doc]。喜欢:

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

    class Meta:
        abstract = True

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

    class Meta:
        abstract = True

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。该模型将不会用于创建任何数据库表。相反,当它用作其他模型的基类时,它的字段将添加到子类的字段中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-18
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 2011-10-24
    • 2019-03-19
    • 1970-01-01
    相关资源
    最近更新 更多