0

我有一个带有条目和容器的应用程序。它们之间存在ManyToMany关系:

  • 一个容器包含 0 个或多个条目
  • 一个条目在 0 个或多个容器中

我对 URI 使用以下架构:

  • 前缀/容器
  • 前缀/容器/条目

这意味着多个 URL 可以指向同一个条目。每个 URL 定义不同的上下文。

我正在尝试为每个容器创建一个 RSS/Atom Feed。我的问题是如何实现Feed.item_link返回正确 URL 的方法。我需要urlresolvers.reverse使用两个参数进行调用:容器标识符和条目标识符。不幸的是 item_link 只接收条目作为参数。只有Feed.get_object方法知道容器。解决此问题的最干净的解决方案是什么?

示例代码如下:

楷模

    class Entry(models.Model):
        pass

    class Container(models.Model):
        entries = models.ManyToManyField("Entries",
                related_name='containers',
                null=True,
                blank=True
        )

网址

    url(r'^prefix/(?P<container_slug>[-\w]+)/rss$', feeds.LatestEntries()),

喂养

    class LatestEntries(Feed):
        title = "foo"
        description = "bar"

        def get_object(self, request, container_slug):
            return get_object_or_404(models.Container, slug=container_slug)

        def item_link(self, entry):
            # TODO: How to pass container_slug to reverse() ?
            return urlresolvers.reverse('up.views.portfolio_image', kwargs={
                    'container_slug': 'FIXME',
                    'entry_slug': entry.slug,
                })
4

1 回答 1

0

使用联合时,由于使用单个实例Feed来处理所有请求,因此情况变得复杂,因此您不能可靠地将值存储为Feed实例的属性,相反,您必须以某种方式使用您创建的对象来传递向前的价值。在这种情况下,我只能想到一种前进的方式,而不是Feed自己重新实现整个班级。

您需要将参数附加到由 返回的对象get_object,例如像这样(尽管在这种情况下此步骤似乎是多余的,因为您的Container实例已经将其作为常规模型字段包含):

def get_object(self, request, container_slug):
    object = get_object_or_404(models.Container, slug=container_slug)
    object.container_slug = container_slug
    return object

然后,在 中items,您必须从容器实例中获取此值并将其附加到返回的每个项目,例如:

def items(self, container):
    result = list(Entry.objects.filter(field__exact=container.something)[:10])
    for entry in result:
        entry.container_slug = container.container_slug
    return result

如果您愿意,可以通过使用闭包和条目列表的生成器来避免在此步骤中枚举查询集,尽管在这种情况下,如果您只返回少数条目,则无关紧要。

然后,最后,您可以item_link像这样实现:

def item_link(self, entry):
    return urlresolvers.reverse('up.views.portfolio_image', kwargs={
            'container_slug': entry.container_slug,
            'entry_slug': entry.slug,
        })
于 2012-11-05T02:02:07.453 回答