【问题标题】:ForeignKey vs CharFieldForeignKey 与 CharField
【发布时间】:2016-02-28 04:37:55
【问题描述】:

我对 django 中的数据模型有一个想法,我想知道是否有人可以指出这两种设置的优缺点。

设置 1:这很明显。对每个对象的每个字段使用 CharFields

class Person(models.Model):
    name = models.CharField(max_length=255)
    surname = models.CharField(max_length=255)
    city = models.CharField(max_length=255)

设置 2:这是我正在考虑的。对包含当前对象应具有的值的对象使用 ForeignKey。

class Person(models.Model):
    name = models.ForeignKey('Name')
    surname = models.ForeignKey('Surname')
    city = models.ForeignKey('City')

class Chars(models.Model):
    value = models.CharField(max_length=255)

    def __str__(self):
        return self.value

    class Meta:
        abstract = True

class Name(Chars):pass
class Surname(Chars):pass
class City(Chars):pass

所以在 setup 1 中,我将创建一个对象:

Person.objects.create(name='Name', surname='Surname', city='City')

每个对象都有自己的数据。在设置 2 中,我必须这样做:

_name = Name.objects.get_or_create(value='Name')[0]
_surname = Surname.objects.get_or_create(value='Surname')[0]
_city = City.objects.get_or_create(value='City')[0]
Person.objects.create(name=_name, surname=_surname, city=_city)

问题:这样做的主要目的是为多个对象重用现有值,但是当您考虑到需要多次点击数据库来创建对象时,这样做值得吗?

【问题讨论】:

  • 我更喜欢第三种设置:gender 是一个整数字段(如果你是更保守的人,则为布尔值:)并且在 django 代码中的某处定义了枚举。
  • 是的,变量是什么无关紧要...我将其更改为城市以避免混淆

标签: python django postgresql django-models


【解决方案1】:

为您的应用程序选择正确的设计模式是一个非常广泛的领域,它受到许多因素的影响,这些因素甚至可能超出堆栈溢出问题的范围。所以从某种意义上说,您的问题可能有点主观而且过于宽泛。

尽管如此,我想说为名字分配一个单独的模型(类),为姓氏分配另一个单独的模型(类)是一种矫枉过正的做法。您最终可能会过度设计您的应用程序。

上述建议背后的主要原因是您可能不希望将名称视为一个单独的实体,并可能为其附加其他属性。除非您真的需要这样的功能,否则名称通常是一些用户碰巧具有相同的纯字符串。

【讨论】:

    【解决方案2】:

    将 name 和 surname 保留为单独的 object/model/db 表没有任何好处。在您的设置中,如果您没有将 name 和 surname 设置为唯一,那么将它们放在单独的模型中没有任何意义。更糟糕的是,它会导致额外的数据库工作并降低性能。现在,如果您将它们设置为唯一的,那么您必须处理这种情况,例如某些用户更改了他的姓名,默认情况下,所有使用该姓名的用户都会更改。

    另一方面,城市 - 没有那么多城市,最好将其保留为单独的对象并通过用户的外键引用它。这将节省磁盘空间,允许轻松获取来自同一城市的所有用户。更好的是,您可以预先填充城市数据库并为进入该城市的用户提供自动完成功能。尽管出于性能考虑,您可能仍希望将 city 作为字符串保留在用户模型中。

    另外,提到“性别”字段,由于该数据没有太多可能的选择,因此值得在代码中使用枚举并将值存储在数据库中,即使用choices 而不是ForeignKey一个单独的数据库表。

    【讨论】:

      猜你喜欢
      • 2013-01-07
      • 1970-01-01
      • 2016-06-30
      • 1970-01-01
      • 1970-01-01
      • 2021-04-20
      • 2021-04-05
      • 2011-12-24
      • 2016-08-10
      相关资源
      最近更新 更多