2016-02-28 48 views
0

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

设置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用于包含当前Object应具有的值的对象。

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 

所以在设置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) 

问:这个主要目的是要重复使用多个对象存在的值,但是这件事值得去做,当你考虑到你需要多个点击数据库来创建一个对象?

+0

我宁愿第三次设置:性别是一个整数字段(或布尔如果你是更保守的人:),并有在Django代码中的某处定义的枚举。 –

+0

是的,这个变量没有什么区别......为了避免混淆,我会将其改为城市 – Ubica

回答

0

为您的应用程序选择正确的设计模式是一个非常广泛的领域,它受到很多因素的影响,甚至可能超出了堆栈溢出问题的范围。所以从某种意义上说,你的问题可能有点主观和太宽泛。不过,我想说为一个名字分配一个单独的模型(类),另一个单独的姓氏等是一个矫枉过正的问题。你可能最终会过度工程你的应用程序。

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

0

将名称和姓氏保存为独立的对象/模型/数据库表格并没有什么好处。在你的设置中,如果你不把名字和姓氏设置为唯一的,那么将它们放在单独的模型中没有任何意义。更糟糕的是,它会导致额外的数据库工作并降低性能。现在,如果你将它们设置为唯一的,那么你必须在例如某些用户更改了他的名字,并且默认情况下会为具有该名字的所有用户更改。

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

另外,提到“性别”字段,因为是这个数据不是很多可能的选择,它的价值在你的代码中使用枚举和存储在DB的值,即使用choices,而不是ForeignKey到一个单独的数据库表。