0

ユーザーがArticleインスタンス(この場合は別のアプリ)に賛成したものを追跡するために指定された2つのモデルがありますarticlescraper

from django.contrib.auth.models import User

class UserProfile(models.Model):
    user = models.OneToOneField(User)

    articles_upvoted = models.ManyToManyField('useraccounts.UpvotedArticle',
                                              null=True,
                                              blank=True)

class UpvotedArticle(models.Model):
    article = models.ForeignKey('articlescraper.Article')
    user = models.ForeignKey(User)

Djangoシェルでは、次の操作を行って記事のリストを取得しようとしましたUserProfile

a = UserProfile.objects.get(pk=1)
a.articles_upvoted.all()

どちらが返されますか:

[]

しかし、それから私はもう少し進んだ:

b = UpvotedArticle.objects.filter(user=User.objects.get(pk=1))
b

どちらが返されますか:

[<UpvotedArticle: Arch Linux Lexmark S305 Drivers>, <UpvotedArticle: Structure of a Haystack project>]

これは予想される動作であり、Django管理者の両方UserProfileUpvotedArticleカテゴリに反映されています。

a.articles_upvoted.all()ただし、 2つのモデルがリンクされている場合、記事のリストを取得しようとして最初に使用した方法で取得できない理由はわかりません。

4

1 に答える 1

2

これらは同じ関係ではないからです。一方にForeignKeyを定義し、もう一方にManyToManyを定義することで、記事の賛成に関する情報を格納するための2つの別々の場所をデータベースに提供しました。

ManyToManyFieldonを削除しUserProfile、自動逆関係を使用する必要があります。

a = UserProfile.objects.get(pk=1)
a.upvotedarticle_set.all()

UpvotedArticleまたは、 ManyToMany関係の「スルー」テーブルとして認識し、 articles_upvoted-の定義で明示的にそのようにマークすることもできます。ただし、関係は:articlescraper.Articleではなくとである必要があります。UpvotedArticle

article_upvoted = models.ManyToManyField(articlescraper.Article, null=True,
                                         blank=True, through=UpvotedArticle)

明示的なスルーテーブルを定義する通常の理由である、その関係に余分なデータを追加しないので、それを完全に削除して、Djangoが作成する自動データに依存することをお勧めします。

于 2012-07-31T07:00:23.870 に答える