Django 反向查找外键

Posted

技术标签:

【中文标题】Django 反向查找外键【英文标题】:Django reverse lookup of foreign keys 【发布时间】:2013-02-24 18:13:03 【问题描述】:

我有一个场地,这个场地有很多活动。我的模型如下所示:

class Event(models.Model):
    title = models.CharField(max_length=200)
    date_published = models.DateTimeField('published date',default=datetime.now, blank=True)
    date_start = models.DateTimeField('start date')
    date_end = models.DateTimeField('end date')
    def __unicode__(self):
        return self.title
    description = models.TextField()
    price = models.IntegerField(null=True, blank=True)
    venue = models.ForeignKey(Venue)

class Venue(models.Model):
    title = models.CharField(max_length=200)
    date_published = models.DateTimeField('published date',default=datetime.now, blank=True)
    venue_latitude = models.CharField(max_length=200)
    venue_longitude = models.CharField(max_length=200)
    venue_address = models.CharField(max_length=200)
    venue_city = models.CharField(max_length=200)
    venue_state = models.CharField(max_length=200)
    venue_country = models.CharField(max_length=200)
    description = models.TextField()
    def __unicode__(self):
        return u'%s' % (self.title)

我想显示在某个地点发生的所有事件。我怎样才能做到这一点?我当前的视图如下所示:

def detail(request, venue_id):
    venue = get_object_or_404(Venue, pk=venue_id)
    return render(request, 'venue-detail.html', 'venue': venue)

【问题讨论】:

这些字段也涉及什么模块 description = models.TextField()? 其实这两个模型都在各自的app里,我只是把它们贴在一起解释一下:) 【参考方案1】:

您可以使用events = venue.event_set 走另一条路。

注意venue.event_set 是一个管理器对象,就像Event.objects,所以你可以调用.all.filter.exclude 和类似的方法来获得一个查询集。

见Django documentation

【讨论】:

太棒了!感谢那。但是,如果我想迭代事件(对于我在事件中),我会得到“'RelatedManager' 对象不可迭代” 您是如何将其更改为 QueryObject 的? @mp3por 场地.event_set.all() 或场地.event_set.filter(),通常。 如果有人仍然看到错误AttributeError: 'Foo' object has no attribute 'bar_set',您可能需要检查related_name 是否设置在子模型的ForeignKey/OneToOneField/ManyToManyField 上(Bar ) 引用父模型 (Foo)。 这个查找会很快吗?他应该向 Venue 添加外键吗?它会让它更快吗?【参考方案2】:

对于那些有“'RelatedManager'对象不可迭代”的人

添加所有以从管理器中检索元素。

% for area in world_areas.all %

https://***.com/a/16909142/2491526 (不能将此添加到第一个答案的评论中)

【讨论】:

你刚刚拯救了我的一天link。 在我发现这个之前,我正要在我的模型中制造混乱:D【参考方案3】:

反过来说。使用Event 模型。

def detail(request, venue_id):
    venue = Event.objects.filter(venue__id=venue_id)
    return render(request, 'venue-detail.html', 'venue': venue)

PS:我从未使用过get_object_or_404()。相应地修改代码。

【讨论】:

那么我可以在我的模板中使用什么来显示场地标题和在这个场地发生的所有事件? 在模板中使用 event.venue.title 或根据您的变量 venue.venue.title :) % for i in venue % i.venue.title 我明白了,但是如何显示在这个场地发生的所有事件? 过滤器返回一个数组,其中包含在场地发生的所有事件。使用for循环模板中的数组 venue = Event.objects.filter(venue__id=venue_id) 我认为这个表达式将返回 Event 对象的 QuerySet 而不是 Venue 对象。

以上是关于Django 反向查找外键的主要内容,如果未能解决你的问题,请参考以下文章

Django-ORM 多对多基本操做!

Django 查询集外键

Django推迟外键查找

Django 啥时候查找外键的主键?

Django:提要的反向查找URL?

如何查找对实例的所有 Django 外键引用