Django联结表与额外的外键

时间:2017-03-10 12:11:59

标签: python sql django many-to-many django-orm

我有以下型号

class Company(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField(
        max_length=500,
        blank=True,
        help_text='Any text to describe a company'
    )
    url = models.URLField('company URL', blank=True, null=True)
    email = models.EmailField(blank=True, null=True)
    created_on = models.DateTimeField('date created', default=timezone.now)

    class Meta:
        verbose_name = 'company'
        verbose_name_plural = 'companies'
        ordering = ['name', '-created_on']

    def __repr__(self):
        return '<Company {0.name}>'.format(self)

    def __str__(self):
        return self.name


class Project(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField(
        max_length=500,
        blank=True,
        help_text='Any text to describe the project'
    )
    company = models.ForeignKey(
        Company,
        on_delete=models.PROTECT,
    )
    created_on = models.DateTimeField('date created', default=timezone.now)

    class Meta:
        verbose_name = 'project'
        verbose_name_plural = 'projects'
        ordering = ['-created_on', 'company']
        permissions = (
            ("can_view_project",
             "Can view all project related work"),
        )

    def __repr__(self):
        return '<Project {0.name}>'.format(self)

    def __str__(self):
        return self.name


class Worker(models.Model):
    description = models.TextField(
        max_length=500,
        blank=True,
        help_text='Optional. Describe what the worker does or who they are'
    )
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    company = models.ForeignKey(Company)

    class Meta:
        order_with_respect_to = 'user'

    def __repr__(self):
        return '<Worker {0.id}'.format(self)

    def __str__(self):
        return self.user.get_fullname()

问题

我想在ProjectWorker之间添加一个ManyToMany关系,以便我可以查看 某个项目下的工人名单。但是,我想确保一个工人只能 如果它们都属于同一家公司,则被添加到项目中。

我计划将一个带有ForeignKey的联结表用于他们的两个公司属性, 但是根据django文档,每个模型只能使用一次外键 (https://docs.djangoproject.com/en/1.10/topics/db/models/#extra-fields-on-many-to-many-relationships

如何确保两个表之间的多对多关系仅限于同一家公司?

是否有另一种方法可以确保工人无法在自己公司以外的项目上工作?

1 个答案:

答案 0 :(得分:1)

假设您在Project模型中以这种方式定义多对多关系:

workers = ManyToManyField(Worker)

假设您有一个名为ProjectForm的模型表单来创建或修改项目。您可以使用以下格式定义clean函数:

def clean(self):
    cleaned_data = super(ProjectForm, self).clean()
    for w in cleaned_data['workers']:
        if w.company.id != cleaned_data['company'].id:
              self.add_error('workers', your_error_message)
              break
    return cleaned_data

希望得到这个帮助。