添加字段到Django多对多模型表的关联表的方法

添加字段到Django多对多模型表的关联表的方法

作者:Wally Yu

CSDN:http://blog.csdn.net/quicktest

微博:http://www.weibo.com/quicktest


最近遇到个麻烦事,想在Django的多对多自动生成的关联表中添加一个字段

原来的模型如下:

class ProjectModule(models.Model):
    name = models.CharField(max_length=100)
    testProject = models.ForeignKey(TestProject)
    needMetaData = models.BooleanField()
    
    def __unicode__(self):
        return self.name
    
    class Meta:
        ordering = ['testProject','name']
        

class Task(models.Model):
    status = models.IntegerField()
    executeTime = models.DateTimeField()
    module = models.ManyToManyField(ProjectModule)
    executor = models.ForeignKey(User)
    automationType = models.ForeignKey(AutomationType)
    browser = models.ManyToManyField(Browser)
    reportLocation = models.TextField()
    VM = models.ManyToManyField(VM)
    
    def __unicode__(self):
        return u'%s: %s' % (self.executor, self.executeTime)
    
    class Meta:
        ordering = ['executeTime']

这样,在数据库中,会自动生成一张关联表:

task_module, 字段如下:

id

task_id

projectmodule_id


现在的问题就是想在task_module关联表中增加一个字段用于存放每一个task的每一个module的上传的metadata文件的地址

用baidu搜了半天也没有找到合适的,找到的解决办法是把一个manytomany拆分成多个foreignkey的方法实现

还是Google给力,不过搜出来的是Django官网的一篇文档:

https://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationships

看来有空去官网学习一下总没有坏处


按照它的解决办法,更改模型如下:

class ProjectModule(models.Model):
    name = models.CharField(max_length=100)
    testProject = models.ForeignKey(TestProject)
    needMetaData = models.BooleanField()
    
    def __unicode__(self):
        return self.name
    
    class Meta:
        ordering = ['testProject','name']
        

class Task(models.Model):
    status = models.IntegerField()
    executeTime = models.DateTimeField()
    module = models.ManyToManyField(ProjectModule, through = 'MetaData')
    executor = models.ForeignKey(User)
    automationType = models.ForeignKey(AutomationType)
    browser = models.ManyToManyField(Browser)
    reportLocation = models.TextField()
    VM = models.ManyToManyField(VM)
    
    def __unicode__(self):
        return u'%s: %s' % (self.executor, self.executeTime)
    
    class Meta:
        ordering = ['executeTime']

class MetaData(models.Model):
    task = models.ForeignKey(Task)
    module = models.ForeignKey(ProjectModule)
    fileLocation = models.TextField()

在定义MetaData的时候也是有限制的,原文如下:

  • Your intermediate model must contain one - and only one - foreign keyto the target model . If youhave more than one foreign key, a validation error will be raised.
  • Your intermediate model must contain one - and only one - foreign keyto the source model . If youhave more than one foreign key, a validation error will be raised.
简单翻译如下:

在中间模型(这里是MetaData)中,必须而且只有一个外键,指向目标模型(这是是Task模型)

在中间模型(这里是MetaData)中,必须而且只有一个外键,指向原始模型(这是是PeojectModule模型)


更改后再去查看数据库结构,发现多了一张“metadata”表,字段如下:

id

task_id

module_id

fileLocation

得到了理想中的表结构


把metadata注册入admin后,再去Django的admin,发现它对于metadata的处理也非常人性化

于是乎,这个问题解决了,记一笔,给遇到类似问题的朋友参考



你可能感兴趣的:(数据库,django,Module,validation,Class,browser)