通过admin.py中表示的ManyToMany关系在我的数据库中添加值

时间:2012-10-16 15:53:11

标签: django django-admin manytomanyfield

我有一个小小的问题,不幸的是,这个问题占用了我所有的时间。

这很简单,我已经有了我的数据库,然后我创建了修改过的models.py和admin.py.一些需要在我的数据库中输入值的员工用户需要最简单的表单。

这是我的数据库:


- 表NGSdbline


CREATE  TABLE IF NOT EXISTS `NGSdb`.`line` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `value` INT NOT NULL ,
  PRIMARY KEY (`id`) )
ENGINE = InnoDB;


CREATE UNIQUE INDEX `value_UNIQUE` ON `NGSdb`.`line` (`value` ASC) ;

- 表NGSdbrun_has_sample_lines


CREATE  TABLE IF NOT EXISTS `NGSdb`.`run_has_sample_lines` (
  `line_id` INT NOT NULL ,
  `runhassample_id` INT NOT NULL ,
  PRIMARY KEY (`line_id`, `runhassample_id`) ,
  CONSTRAINT `fk_sample_has_line_line1`
    FOREIGN KEY (`line_id` )
    REFERENCES `NGSdb`.`line` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_sample_has_line_run_has_sample1`
    FOREIGN KEY (`runhassample_id` )
    REFERENCES `NGSdb`.`run_has_sample` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)

- 表NGSdbrun_has_sample


CREATE  TABLE IF NOT EXISTS `NGSdb`.`run_has_sample` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `run_id` INT NOT NULL ,
  `sample_id` INT NOT NULL ,
  `dna_quantification_ng_per_ul` FLOAT NULL ,
  PRIMARY KEY (`id`, `run_id`, `sample_id`) ,
  CONSTRAINT `fk_run_has_sample_run1`
    FOREIGN KEY (`run_id` )
    REFERENCES `NGSdb`.`run` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_run_has_sample_sample1`
    FOREIGN KEY (`sample_id` )
    REFERENCES `NGSdb`.`sample` (`id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)

这是我的models.py:

class Run(models.Model):
    id = models.AutoField(primary_key=True)   
    start_date = models.DateField(null=True, blank=True, verbose_name='start date')
    end_date = models.DateField(null=True, blank=True, verbose_name='end date')
    project = models.ForeignKey(Project)
    sequencing_type = models.ForeignKey(SequencingType)
    def __unicode__(self):
        return u"run started %s from the project %s" % (self.start_date,self.project)


class Line(models.Model):
    id = models.AutoField(primary_key=True)
    value = models.IntegerField()
    def __unicode__(self):
        return u"%s" % str(self.value)


class RunHasSample(models.Model):
id = models.AutoField(primary_key=True)
run = models.ForeignKey(Run)
sample = models.ForeignKey(Sample)
dna_quantification_ng_per_ul = models.FloatField(null=True, blank=True)
lines = models.ManyToManyField(Line)
def __unicode__(self):
    return u"Sample %s from run %s" % (self.sample, self.run)

这是我的admin.py:

class RunHasSamplesInLine(admin.TabularInline):
    model = RunHasSample
    fields = ['sample', 'dna_quantification_ng_per_ul', 'lines']    
    extra = 6

class RunAdmin(admin.ModelAdmin):
    fields = ['project', 'start_date', 'end_date', 'sequencing_type']
    inlines = [RunHasSamplesInLine]
    list_display = ('project', 'start_date', 'end_date', 'sequencing_type') 

如您所见,我的样本在运行表单中以行显示,以便员工可以轻松地填满数据库。 当我尝试填充数据库时,我有这个错误:

  

(1054,“字段列表'中的未知列'run_has_sample_lines.id'”)

当然,我的数据库中没有字段“行”!这是一个多对多的领域,所以我已经创建了我的中间表!

好的,好的!所以我尝试为中间表(run_has_sample_lines)创建模型,并在RunHasSample模型中的ManyToManyField中添加“through”。但是,当我手动添加“直通”时,我无法使用ManyToMany字段。向管理视图添加行的唯一方法是将它们堆叠成行...正如您所看到的那样,样本已经在行中,不可能在已经在行样本中添加新的“内联”... < / p>

最后,我试着看看django用manage.py sqlall创建了什么。 我明白了:

 CREATE TABLE `run_has_sample_lines` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `runhassample_id` integer NOT NULL,
    `line_id` integer NOT NULL,
    UNIQUE (`runhassample_id`, `line_id`)
)
;
ALTER TABLE `run_has_sample_lines` ADD CONSTRAINT `line_id_refs_id_4f0766aa` FOREIGN KEY (`line_id`) REFERENCES `line` (`id`);

似乎run_has_sample表上没有外键,而我首先在数据库中创建了它。我想问题来自这里,但我无法解决它,我真的希望你能......

非常感谢!

2 个答案:

答案 0 :(得分:0)

您可能希望在多对多关系上尝试'through'属性,并在Django中声明您的中间表。

答案 1 :(得分:0)

我发现问题出在哪里......

这不是ManyToManyField中的问题,而是在中间表中。 Django拒绝我的中间表没有唯一的ID!

因此,在创建django的sql中,它自动创建了一个名为“id”的唯一id,但是在我的数据库中我没有创建一个(因为两个外键通常就足够了)。

下次,我会更加小心。