2

ManyToMany リレーションシップにスルー テーブルを介した余分なデータがある場合、テンプレート内のデータにアクセスするにはどうすればよいでしょうか? パラメータを指定すると、ビューからデータを取得できます。

class Category(models.Model):
    title           = models.CharField(max_length=1024,null=True,blank=True)
    entry           = models.ManyToManyField(Entry,null=True,blank=True,
                                             related_name='category_entry',
                                             through='CategoryEntry',
                                             )

class CategoryEntry(models.Model):
    category    = models.ForeignKey(Category)
    entry       = models.ForeignKey(Entry)
    votes       = models.IntegerField(null=False, default=0)

def category_detail(request, pk):
    category = models.Category.objects.select_related().get(pk=pk)
    entries  = category.entry.order_by('-temp_sort_order').filter(temp_sort_order__gte=0)
    for entry in entries:
        assert isinstance(entry, models.Entry)
        ce = models.CategoryEntry.objects.get(entry=entry, category=category)
        pprint('Show votes as a test: ' + ce.votes) #OK
        pprint('entry title: ' + entry.title) #OK
        pprint('entry votes: ' + str(entry.category_entry.votes)) #BAD
        pprint('entry votes: ' + str(entry.entry.votes))  #BAD
    ....

ただし、テンプレートはメソッドにパラメーターを提供できません。

https://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationshipsのドキュメントでは、テンプレートについては言及されていません。使用するfor entry in category.category_entry_set.allと、'Category' オブジェクトに属性 'category_entry_set' がありません。 category.category_entry.allどちらも機能しません。

最終的に、追加のデータをテンプレートに表示したいと思います。

{% for entry in entries %}
    <ul>
        <li>Title: {{ entry.title }} Votes: {{ entry.category_entry.votes }} {{ entry.entry.votes }}</li>
    </ul>
{% endfor %}
4

3 に答える 3

2

テンプレートにカテゴリ インスタンスがある場合:

category.entry.all -> list of entries

テンプレートにエントリ インスタンスがある場合:

entry.category_entry.all -> list of categories

M2M フィールドは複数形で呼び出す必要があります。そうすれば、より読みやすいコードが得られます。

category.entries.all

%model%_set 構文 (指定した場合は関連する名前) は、後方関係を介してモデルにアクセスするために使用されます。

https://docs.djangoproject.com/en/1.4/topics/db/queries/#following-relationships-backward

しかし、m2m インスタンスに関連付けられた「投票」を取得するにはどうすればよいでしょうか? – ブライス

次の方法をお勧めします。

class Category(models.Model):
    title           = models.CharField(max_length=1024,null=True,blank=True)
    entries           = models.ManyToManyField(Entry,null=True,blank=True,
                                             related_name='categories',
                                             through='CategoryEntry',
                                             )

class CategoryEntry(models.Model):
    category    = models.ForeignKey(Category, related_name='category_entries')
    entry       = models.ForeignKey(Entry)
    votes       = models.IntegerField(null=False, default=0)

def category_detail(request, pk):
    category = models.Category.objects.select_related().get(pk=pk)
    category_entries  = category.category_entries.filter(entry__temp_sort_order__gte=0).order_by('-entry__temp_sort_order')
    for category_entry in category_entries:
        # category_entry is an instance of the model CategoryEntry
        pprint('category entry votes: ' + str(category_entry.votes))
        pprint('entry title: ' + category_entry.entry.title)
   ....

HOW TO
entry = Entry.objects.get(pk=1)
entry.categories.all() # list of categories (here we work through related name of the field entries)

category = Category.objects.get(pk=1)
category.entries.all() # list of entries (here we work through m2m field entries)

category.category_entries.all() # list of CategoryEntry objects (through related name category_entries of the field category in model CategoryEntry)
于 2012-07-16T07:37:45.920 に答える
1

あなたの場合、アンドレイが言ったように、カテゴリからエントリを取得する正しい方法は次のとおりです。

category.entry.all()

ここで、反復と順序に関する質問に対処します。Python では、次のようになります。

for ce in category.categoryentry_set.order_by('-votes'):
    print ce.entry, ce.votes

これにより、投票順に並べられた各カテゴリのエントリが表示されます。これをテンプレートにするには、クエリセットcategory.categoryentry_set.order_by('-votes')を変数に保存して反復処理するだけです。

于 2012-07-14T00:37:20.530 に答える
0

これは、機能する醜い醜いハックです。フィルターと並べ替えの後、リストを処理し、追加のモデル フィールドを追加します。テンプレートに簡単にアクセスできるようになりました。

entries  = category.entry.order_by('-temp_sort_order').filter(temp_sort_order__gte=0)
for entry in entries:
    assert isinstance(entry, models.Entry)
    ce = models.CategoryEntry.objects.get(entry=entry, category=category)
    entry.xxx_votes = mark_safe(ce.votes)  # use {{ entry.xxx_votes to access }}
    entry.xxx_ce    = ce  # Use {{ entry.ce.votes to access }}
return render_to_response('category.html')

うまくいけば、誰かがより良い答えを提供したり、django 自体の改善を提案したりできます。この解決策では、並べ替えができません:category.entry.order_by('-category_entry.votes')

于 2012-07-16T19:48:10.383 に答える