2009-09-16 8 views
6

私はDjangoで新しく、manytomany relatiosnhipsとManytoone(つまりForeign Key)の周りに私の心をつかむ問題がいくつかあります。Djangoの関係

私の設定はこれです。

は、私は、クラスA、クラスB、クラスCは

すべてのクラスBのオブジェクトはオブジェクトクラスに属している必要があります持っています。それらは、複数のクラスAオブジェクトに属することはできません。より実用的な例は、クラスAが音楽バンドであり、クラスBがそのバンドの曲である場合であり得る。ほとんどのバンドは複数のソングを持ちますが、すべてのソングはバンドに属していなければなりません(この例では、複数のバンドを持つことはできません)。

クラスCは個々のバンドメンバーのリストです。したがって、すべてのバンドメンバーは任意の数の曲だけでなく、任意の数のバンドに関連付けることができます。つまりバンドXのメンバーもバンドY.

のメンバーになることができます私の質問は、私は、この文脈でのForeignKeyや多対多の関係を使用する方法

でしょうか?

この例は、自分の状況をわかりやすくして問題の説明に役立てるために作成したものです。私は管理者にクラスCオブジェクトがどのクラスBオブジェクトまたはクラスCオブジェクトが属するクラスAオブジェクトを表示するようにしたいと思います。

クラスAオブジェクトを見る場合、その特定のクラスAオブジェクトに属するすべてのクラスBオブジェクトのリストを見ることができます。

すべての入力が高く評価されています。

+1

Manytooneで管理者のカスタマイズにより詳細な紹介を得ることができますか?それはスコットランドのどこかですか? – ijw

答えて

3

これはすべてかなり簡単です。私は以下の記述的な名前を使用して、それを簡単にするようにしました。ここで

class Band(models.Model): 
    name = models.CharField(max_length=255) 

class BandMember(models.Model): 
    name = models.CharField(max_length=255) 
    bands = models.ManyToManyField(Band) 

class Song(models.Model): 
    name = models.CharField(max_length=255) 
    band = models.ForeignKey(Band) 

# get a band 
myband = Band.objects.get(name='myband') 

# all songs from that band 
print myband.song_set.all() 

# all members of that band 
print myband.bandmembers.all() 


# get a specific band member 
dave = BandMember.objects.get(name='Dave') 

# what bands is Dave a member of? 
print dave.bands.all() 

# what songs has Dave sung? (slightly more complicated) 
print Song.objects.get(band__bandmember=dave) 
+0

+1 - 偉大な答え - 'ManyToManyField( 'Band')'しかし、 'ForeignKey(Band)'を持っている理由を編集する価値があるかもしれません。それぞれのクラスが定義されている順序とは関係なく、それぞれ「ForeignKey」を使用します。 –

+0

良い点は、私は実際にクラスを並べ替えたので、文字列フォームを使用する必要はありません。 –

+0

こんにちは お返事ありがとうございます。私はあなたの答えを理解していますが、現時点では管理ページです。私が新しいBandMemberに入ると、彼はどの曲が接続されているかを尋ねられます。バンドメンバーを開くと、すべての曲のIDを含むようなドロップリストが表示されます。 バンドメンバー(バンドテーブルにもある特定のID nrを持つ)を入力すると、バンドメンバーを見るときに作成された後、管理者はこれを表示する必要があります。これを行うには管理者向けの特別なビューを作成する必要がありますか? – Consiglieri

11

は、私はそれを設定したい方法です(であなたのmodels.py)このように設定

class Member(models.Model): 
    name = models.CharField(max_length=100) 
    ... 

    def __unicode__(self): 
     return self.name 


class Band(models.Model): 
    name = models.CharField(max_length=100) 
    members = models.ManyToManyField(Member) 
    ... 

    def __unicode__(self): 
     return self.name 


class Song(models.Model): 
    name = models.CharField(max_length=100) 
    band = models.ForeignKey(Band) 
    ... 

    def __unicode__(self): 
     return self.name 

  • member.band_set.all()

  • にあなたのメンバーが所属する全ての帯域を提供しますband.members.all()はあなたにバンドのメンバーを与えます
  • song.bandは、その曲
  • band.song_set.all()のためにあなたのバンドを与えるバンドのメンバーにband_setsong_setは「逆」の関係であることをあなたにバンド

注すべての曲を提供します。それらはモデルでは明示的に定義されていませんが、Djangoはそれらをあなたのために透過的に設定します。これらは、フィールド定義のrelated_nameパラメーターを使用してカスタマイズできます。例:

class Band(models.Model): 
    members = models.ManyToManyField(Member,related_name='bands') 

は、次のようにあなたがメンバーのためにすべてのバンドを取得してみましょうになります。

member.bands.all() 

管理者は、自動的に次を提供します:

  • は、内バンドのメンバー全員を表示複数選択リスト
  • 単一の選択リストに曲のバンドを表示

しかし、バンドの曲を見たい場合は、少しの管理者のカスタマイズが必要です。あなたのadmin.py

from django.contrib import admin 

class SongInline(admin.StackedInline): 
    model = Song 
    extra = 1 

class BandAdmin(admin.ModelAdmin): 
    inlines = [SongInline] 

admin.site.register(Band,BandAdmin) 
admin.site.register(Member) 
admin.site.register(Song) 

これは、あなたが右の管理ページから曲を表示できるようになる - と同様にそれらを編集したり、追加します!このテンプレートに従うことで、メンバーのすべてのバンドを表示することもできます。

あなたはhttp://docs.djangoproject.com/en/dev/intro/tutorial02/

+0

+1を含めるとadmin.py – Alasdair

+0

ありがとうございます、回答は非常に早く来て、私は追いつくことができました:)。 私はそれを渦巻きにして、私があなたの提案と共に働くことができるかどうかを見てください。 – Consiglieri

+0

もう一度、それは動作しているようだ - バンドでは、メンバの名前ではなく "memmberオブジェクト"が表示されます。私はlist_displayを行うことができますが、別のクラスのmemebrにlist_displayを設定する方法はわかりません。つまり、List_display =( 'Member.firstname'、 'Memeber.lastname')を使ったBandAdminクラスでは動作せず、上記のlist_displayでMemberAdminクラスを設定すると、Memeberのリストにリスト表示されますが、バンドビューには「メンバーオブジェクト」が表示されますが、メンバー名は表示されません。私はこれが自明だと確信していますが、これに援助の手を感謝するでしょう – Consiglieri