Джанго Отношения - PullRequest
       16

Джанго Отношения

6 голосов
/ 16 сентября 2009

Я новичок в Django, и у меня есть несколько проблем, когда я думаю о многих отношениях и Manytoone (т.е. внешнем ключе).

Моя настройка такова.

У меня есть класс A, класс B, класс C

Каждый объект класса B должен принадлежать объекту класса A. Они не могут принадлежать более чем одному объекту класса А. Более практичным примером может быть, если класс A - музыкальная группа, а класс B - песня с этой группой. У большинства групп будет более одной песни, но каждая песня должна принадлежать группе (в этом примере песня не может иметь несколько групп).

Класс C - это список отдельных участников группы. Таким образом, каждый участник группы может быть связан с произвольным количеством песен, а также с произвольным числом групп. Другими словами, член группы X также может быть членом группы Y.

Тогда мой вопрос будет

Как бы я использовал отношения ForeignKey и ManytoMany в этом контексте?

Этот пример придуман, чтобы облегчить понимание моей ситуации и помочь мне объяснить мою проблему. Я хотел бы, чтобы администратор отображал для каждого объекта класса C, какие объекты класса B или объекты класса A принадлежат классу C. То же самое относится к классу B и классу A.

Если вы посмотрите на объекты класса A, вы сможете увидеть список всех объектов класса B, которые принадлежат этому конкретному объекту класса A.

Любой вклад приветствуется.

Ответы [ 2 ]

11 голосов
/ 16 сентября 2009

Вот как я бы это настроил (в вашем 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_set на элементе и song_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/

3 голосов
/ 16 сентября 2009

Это все довольно просто. Я использовал описательные имена ниже, чтобы им было легче следовать.

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)
...