15

自分と関係のあるモデルが欲しいのですが、ManyToManyどうやって書くのかわかりませんが、やりたいことを説明するコードを書いてみます。

class Person(models.Model):
   name = models.CharField()
   occupation = models.CharField()

   friends = models.ManyToManyField('self', through = PersonFriends)

友達に見てもらいたいモデル

class PersonFriends(models.Model)
   ???
   comment = models.CharField()

たとえば、他のモデルの名前が「Pet」の場合、through関係のあるManyToManyフィールドでは、そのフィールドにthrough classという名前を付けて、モデルにします。そして例えばpersonpetForeignKey(Person)Pet

同じモデルになった2人のフィールドのモデルで、fields自分の名前を何に付けますか?PersonFriends

4

4 に答える 4

23

あなたはこのようなことをすることができます:

class Person(models.Model):
    name = models.CharField(max_length = 255)
    occupation = models.CharField(max_length = 255)
    friends = models.ManyToManyField('self', through = 'PersonFriends', 
          symmetrical = False)
    #     ^^^^^^^^^^^
    # This has to be false when using `through` models. Or else your 
    # model will not validate.

class PersonFriends(models.Model):
    source = models.ForeignKey(Person, related_name = 'source')
    #                                  ^^^^^^^^^^^^
    # You need different `related_name` for each when you have 
    # multiple foreign keys to the same table. 

    target = models.ForeignKey(Person, related_name = 'target')
    comment = models.CharField(max_length = 255)
于 2010-10-07T10:08:11.510 に答える
4

すべてがManyToManyField.through_fieldsの公式ドキュメントに記載されています(そこで「再帰的関係」フレーズを検索して、必要なものをすばやく見つけることができます)。

django 1.11の場合、throughおよび(!)through_fields引数を指定する必要があります。

class Person(models.Model):
    name = models.CharField(max_length=50)

    # note the additional arguments here
    friends = models.ManyToManyField(
        'self',

        # recursive relationships to self with intermediary
        # through model are always defined as non-symmetrical
        symmetrical=False,

        through='PersonFriend',

        # this argument is required to define a custom
        # through model for many to many relationship to self
        # position matters: 1 - source (from), 2 - target (to)
        through_fields=('person', 'friend'),        
    )


class PersonFriend(models.Model):
    # required relationship-defining foreign keys
    # (note that the order does not matter, it matters
    # in 'through_fields' argument in 'friends' field of the 'Person' model)
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    friend = models.ForeignKey(Person, on_delete=models.CASCADE)

    # additional fields
    comment = models.CharField()
于 2017-07-01T20:35:03.817 に答える
3

友情が対称的であると仮定せずに。バズ・ライトイヤーはウッディの友達かもしれませんが、ウッディは映画の終わり近くまでバズ・ライトイヤーと友達ではないからです。両方のモデルを単純化しても、妥当なルックアップ名を使用できます。もちろん、友情が良好な場合は、必ず2人のPersonFriendsを定義する必要があります。

class Person(models.Model):
   name = models.CharField()
   occupation = models.CharField()

class PersonFriends(models.Model):
    from_person = models.ForeignKey(Person, related_name='friends_with')
    to_person = models.ForeignKey(Person, related_name='friends')
    comment = models.CharField()
    class Meta:
        unique_together = ('from_person', 'to_person')

これには、友情の方向ごとにコメントのボーナスが追加されています。つまり、ティリオンは、サンサは素敵で知的な、しかし失われた少女だと考えています。一方、サンサは、ティリオンは醜いが賢くて心の優しい人だと思うかもしれません。

于 2014-12-18T11:30:58.193 に答える
2
class PersonFriends(models.Model):
    from_person = models.ForeignKey(Person, related_name='from_person')
    to_person = models.ForeignKey(Person, related_name='to_person')

これは、私のモデル構造からの自己への多対多関係のデータベーステーブル構造からのものです。Djangoはそれをそのように定義しています。

于 2010-10-07T10:05:03.587 に答える