【问题标题】:Django: How to use same abstract class twice with same fields but different names?Django:如何使用相同的抽象类两次具有相同的字段但不同的名称?
【发布时间】:2021-07-09 06:04:06
【问题描述】:

我有一个名为 Address 的抽象模型,其中包含 address_linepostcode 等字段。

现在我想创建一个模型Person,它有多种类型的地址,如residential_addressoffice_address 等。我怎样才能在 Django 中实现呢?

我的Address 模特:

class Address(Model):

    address_line_one = CharField(
        blank=True,
        null=True,
        max_length=255,
    )

    address_postcode = CharField(
        blank=True,
        null=True,
        max_length=50,
        validators=POSTCODE_VALIDATORS
    )

    class Meta(GlobalMeta):
        abstract = True

我的Person 班级:

class Person(Address, Model):
    name = CharField(
        blank = True
        max_length = True
    )
    class Meta:
    app_label = "person"
    
)

forms

class PersonForm(forms.ModelForm):
    class Meta:
        model = Person
        exclude = []
        widgets = {}

form.html

<div>
    {% form.name %}
</div>

【问题讨论】:

  • 您的示例代码可能不正确,请检查。

标签: django django-models django-views django-forms django-templates


【解决方案1】:

您不应该在 Person 类中从 Address 继承。继承的基本前提是“Is a”关系,即您的代码最终会说“Person is an Address”这是错误的!就面向对象编程而言,您想要的是Aggregation。您可以使用外键在数据库/Django 模型中执行此操作。

在 Django 中,您可以使用 ForeignKey [Django doc] 字段来模拟此类关系:

from django.db import models


class Address(Model):

    address_line_one = CharField(
        blank=True,
        null=True,
        max_length=255,
    )

    address_postcode = CharField(
        blank=True,
        null=True,
        max_length=50,
        validators=POSTCODE_VALIDATORS
    )

    class Meta(GlobalMeta):
        # This should not be abstract
        # abstract = True


class Person(Model):
    name = CharField(
        blank = True
        max_length = 50 # This must be a number
    )
    residential_address = models.ForeignKey(
        Address,
        on_delete=models.CASCADE,
        related_name='residing_people'
    )
    office_address = models.ForeignKey(
        Address,
        on_delete=models.CASCADE,
        related_name='office_people'
    )
    
    class Meta:
        app_label = "person"

【讨论】:

  • 我实际上不能使Address 非抽象,因为它在整个代码中都被使用。另外,我不想为Address创建一个表
  • @Rachit 看来您需要对数据库规范化和 OOPS 概念进行一些研究,因为您非常滥用这些概念。一个新的地址表实际上是一个很好的设计,因为您可以通过这种方式重用代码。
  • 我明白你的意思,但这就是旧代码库的设置方式。不幸的是,公司没有预算来迁移遗留代码,我将不得不处理给定的内容
猜你喜欢
  • 1970-01-01
  • 2017-03-03
  • 1970-01-01
  • 2011-06-01
  • 2021-03-20
  • 1970-01-01
  • 2022-12-05
  • 1970-01-01
  • 2016-08-25
相关资源
最近更新 更多