0

エントリとコンテナを含むアプリケーションがあります。それらの間にはManyToManyの関係があります。

  • コンテナに0個以上のエントリが含まれている
  • エントリが0個以上のコンテナにある

URIには次のスキーマを使用します。

  • プレフィックス/コンテナ
  • プレフィックス/コンテナ/エントリ

これは、複数のURLが同じエントリにつながる可能性があることを意味します。各URLは異なるコンテキストを定義します。

コンテナごとにRSS/Atomフィードを作成しようとしています。私の問題はFeed.item_link、正しいURLを返すメソッドを実装する方法です。urlresolvers.reverseコンテナ識別子とエントリ識別子の2つの引数を使用して呼び出す必要があります。残念ながら、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

    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この場合、クラス全体を自分で再実装する以外に、先に進む方法は 1 つしか考えられません。

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 に答える