Django管理员,多对多领域,几个重复的条目

时间:2012-05-06 22:53:25

标签: django django-models django-admin many-to-many

我有一种情况,我正在尝试为作曲家创建一个快速简单的管理界面,以便在一段音乐中列出乐器。我正在寻找的是一个单一的实体,一个仪器,它定义了一个特定的仪器组合。例如,萨克斯管四重奏可能包括:

  1. Soprano sax
  2. Alto sax
  3. Tenor sax
  4. 男中音萨克斯
  5. 但它也可能包括两个altos,男高音和男爵。当你试图添加整个部分时(例如第一把小提琴 - 多达18个成员),问题会变得更糟。

    我想出的初始模型如下:

    class Work(Post):
        authors = models.ManyToManyField(Individual)
        title = models.CharField(max_length=255)
        subtitle = models.CharField(max_length=255, blank=True)
        program_notes = models.TextField(blank=True)
        notes = models.TextField(blank=True)
        media = models.ManyToManyField('Upload')
    
    class Composition(Work):
        instrumentation = models.ForeignKey('Instrumentation')
    
    class Instrumentation(models.Model):
        forces = models.ManyToManyField(Instrument)
        types = models.ManyToManyField('InstrumentationType')
    
    class InstrumentationType(models.Model):
        type = models.CharField(max_length=255)
        variation = models.SmallIntegerField(default=0)
        created = models.DateTimeField(auto_now_add=True)
        modified = models.DateTimeField(auto_now=True)
    

    我计划稍后将乐器中的每个乐器映射到排练,音乐会等表演者,所以这不仅仅是我需要的简单计数。如果我这样做没有django(即只是SQL和数据库设计),我会有一个映射表

    仪器:

    • id(int serial PK),
    • type(FK),
    • composition_id(FK),
    • instrument_id(FK)

    看起来Django正在为我在数据库中创建这种确切的情况,但由于某种原因,框架需要typecomposition_idinstrument_id一起是唯一的。管理界面(多选框)也清楚地表明,拥有多个相似的条目并不是多对多字段的设计方式。那我该怎么做呢?有没有确定的解决方法呢?

1 个答案:

答案 0 :(得分:1)

this question选择的答案解决了这个问题。我需要显式定义映射表,然后使用admin inline功能来修复接口。

<强> models.py:

class Instrumentation(models.Model):
    forces = models.ManyToManyField(Instrument, through='InstrumentationForces')
    types = models.ManyToManyField('InstrumentationType')

class InstrumentationForces(models.Model):
    instrument = models.ForeignKey(Instrument)
    instrumentation = models.ForeignKey(Instrumentation)

<强> admin.py:

class InstrumentInline(admin.TabularInline):
    model = InstrumentationForces
    extra = 3

class InstrumentationAdmin(admin.ModelAdmin):
    filter_horizontal = ('types',)
    inlines = (InstrumentInline,)
admin.site.register(Instrumentation, InstrumentationAdmin)