2009-09-16 4 views
6

Я новичок в Django, и у меня есть несколько проблем, связанных с множеством реляционных отношений и Manytoone (например, Foreign Key).Django Отношения

Моя установка - это.

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

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

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

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

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

Этот пример надуман только для того, чтобы упростить мою ситуацию и помочь мне объяснить мою проблему. Я бы хотел, чтобы администратор отображал для каждого объекта класса C объекты класса B или объекты класса А, принадлежащие классу C. То же самое относится к классу B и классу 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)', потому что в настоящее время похоже, что так вы должны определить 'ManyToManyField' и' ForeignKey' соответственно, вместо того, чтобы делать с порядком, в котором были определены классы. –

+0

Хорошо, я действительно переупорядочил классы, поэтому нет необходимости использовать строчную форму. –

+0

Привет Спасибо за ответ. Я понимаю ваш ответ, но проблема на данный момент - это страница администратора. Если я вхожу в новый BandMember, мне будет предложено сказать, к каким песням он подключен. И если я открою член группы, я могу выбрать список, который, как представляется, содержит идентификатор каждой песни. Если я вхожу в bandmember (который имеет определенный 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() дает членам группы
  • дает группу для этой песни
  • band.song_set.all() дает все песни для группы

Обратите внимание, что band_set на член и song_set на полосе «Reverse» отношения. Они явно не определены в моделях, но 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

Привет, мне кажется, что все работает, хотя в Band он onlky отображает «объект memmber», а не имя участника. Я знаю, что могу сделать list_display, но не знаю, как установить list_display на memebr другого класса. т.е. в классе BandAdmin с использованием list_display = ('Member.firstname', 'Memeber.lastname') не работает, и если я установил класс MemberAdmin с указанным выше list_display, он получит отображение списка в файле Memeber viw, но список в В полотном представлении показывается только «объект-член», но не имя члена. Я уверен, что это тривиально, но я бы оценил руку помощи на этом – Consiglieri

Смежные вопросы