为什么是models.ForeignKey有利?

时间:2012-02-06 06:43:14

标签: python django

在我的模型中,我有一个Concert类和一个Venue类。每个场地都有多场音乐会。我一直用一个简单的

将Concert课程连接到一个Venue

venue = models.IntegerField(max_length = 10)

...包含场地对象的主键。一位同事建议我们改用venue = models.ForeignKey(Venue)。虽然这也有效,但我想知道是否值得转换,因为我能够通过简单地在Concert.objects.filter(venue=4)中使用场地ID来解析场地的所有音乐会,就像我用{{1}那样做}:ForeignKey。我使用我的方法时从来没有遇到任何问题。

我看到它的方式,使用Venue_instance.Concert_set.all()IntegerFieldobjects.filter()的“ManyToOne”关系一样多,所以我想知道我哪里错了。为什么ForeignKey有利?它们更快吗?它是更好的数据库设计吗?清洁代码?

2 个答案:

答案 0 :(得分:3)

我想说外键最实用的好处是能够自动查询关系。 Django自动生成JOIN。

你提到的自动反向关系助手也很棒。

以下是一些只有整数关系会更复杂的例子。

concerts = Concert.objects.filter(...)

concerts.order_by('venue__attribute') # ordering beyond PK.
concerts.filter(venue__name='foo') # filter by a value across the relationship
concerts.values_list('venue__name') # get just venue names
concerts.values('venue__city').annotate() # get unique values across the venue

concerts.filter(venue__more__relationships='foo')

Venue.objects.filter(concert__name='Coachella') # reverse lookups work too

# with an integer field for Concert.venue, you'd have to do something like...
Venue.objects.filter(id__in=Concert.objects.filter(name='Coachella')) 

正如其他人指出的那样......数据库完整性很有用,级联删除(当然可以自定义)和 facepalm 我刚刚想到django管理员和表单框架使用外键工作得非常好。

class ConcertInline(admin.TabularInline):
    model = Concert

class VenueAdmin(admin.ModelAdmin):
    inlines = [ConcertInline]
    # that was quick!

我确信有更多django功能处理外键的例子。

答案 1 :(得分:3)

ForeignKey是大多数数据库中实施的database concept,也强制执行referential integrity

因为django会知道这个列引用的是一个表,它本身可能是某个其他表的外键,它可以帮助链接将在SQL中产生相应连接的关系。

除了正常的单向链接之外,Django还向对方添加了一个参数,就像你已经认识到的那样。当您拥有场地实例时,您可以查询venue.concert_set

最让我烦恼的是不使用FK并使用整数滚动自己的东西:

  • 您没有参照完整性检查。
  • 你失去了SQL的力量。您的每次中等深度查询现在都需要多次点击数据库,因为您无法加入。 - 你也失去了框架提供的处理SQL的所有杠杆