【问题标题】:Adding a UniqueConstraint to a ManyToMany field将 UniqueConstraint 添加到 ManyToMany 字段
【发布时间】:2020-12-18 13:47:54
【问题描述】:

我想在我的数据库中添加一个约束,以便一个应用程序只能与一个空缺相关联。我不想从 shell 或 django 管理页面进入,进入一个空缺并选择一个已经与空缺相关联的应用程序。我想提出某种验证错误。但我有点不确定我应该怎么做?

models.py

class Vacancy(models.Model):
    CATEGORY_CHOICES = [
        ('ADMINISTRATION', 'Administration'),
        ('CONSULTING', 'Consulting'),
        ('ENGINEERING', 'Engineering'),
        ('FINANCE', 'Finance'),
        ('RETAIL', 'Retail'),
        ('SALES', 'Sales'),
    ]
    employer = models.ForeignKey('Employer', on_delete=models.CASCADE)
    job_title = models.CharField(max_length=35, default=None)
    main_duties = models.TextField(default=None, validators=[
        MinLengthValidator(650),
        MaxLengthValidator(2000)
    ])
    person_spec = models.TextField(default=None, validators=[
        MinLengthValidator(650),
        MaxLengthValidator(2000)
    ])
    salary = models.PositiveIntegerField(default=None, validators=[
        MinValueValidator(20000), 
        MaxValueValidator(99000)
    ])
    city = models.CharField(choices=CITY_CHOICES, max_length=11, default=None)
    category = models.CharField(choices=CATEGORY_CHOICES, max_length=15, default=None)
    max_applications = models.PositiveSmallIntegerField(blank=True, null=True)
    deadline = models.DateField(default=None)
    applications = models.ManyToManyField('Application', blank=True, related_name='submissions')
    

    class Meta:
        verbose_name_plural = 'vacancies'
        constraints = [
            models.UniqueConstraint(fields=['id', 'applications'], name="unique_application")
        ]


class Application(models.Model):
    STAGES = [
        ('pre-selection', 'PRE-SELECTION'),
        ('shortlisted', 'SHORTLISTED'),
        ('rejected pre-interview', 'REJECTED PRE-INTERVIEW'),
        ('rejected post-interview', 'REJECTED POST-INTERVIEW'),
        ('successful', 'SUCCESSFUL')
    ]
    candidate = models.ForeignKey('Candidate', on_delete=models.CASCADE)
    job = models.ForeignKey('Vacancy', on_delete=models.CASCADE)
    cv = models.CharField(max_length=60, default=None)
    cover_letter = models.TextField(default=None, validators=[
        MinLengthValidator(0),
        MaxLengthValidator(2000)
    ])
    submitted = models.DateTimeField(auto_now_add=True)
    stage = models.CharField(choices=STAGES, max_length=25, default='pre-selection')

如你所见,我在 Vacancy 模型中添加了一个约束:

constraints = [
            models.UniqueConstraint(fields=['id', 'applications'], name="unique_application")
        ]

但是当我执行makemigrations 然后migrate 时,我得到了这个错误:

    raise FieldDoesNotExist("%s has no field named '%s'" % (self.object_name, field_name))
django.core.exceptions.FieldDoesNotExist: NewVacancy has no field named 'applications'

我不清楚这是什么意思。

有什么想法吗?

【问题讨论】:

    标签: python django django-models many-to-many unique-constraint


    【解决方案1】:

    听起来像是一对多的关系。您可以使用related_name=applications 而不是ManyToManyField 移动到Application 上的ForeignKey

    class Vacancy(models.Model):
        CATEGORY_CHOICES = [
            ('ADMINISTRATION', 'Administration'),
            ('CONSULTING', 'Consulting'),
            ('ENGINEERING', 'Engineering'),
            ('FINANCE', 'Finance'),
            ('RETAIL', 'Retail'),
            ('SALES', 'Sales'),
        ]
        employer = models.ForeignKey('Employer', on_delete=models.CASCADE)
        job_title = models.CharField(max_length=35, default=None)
        main_duties = models.TextField(default=None, validators=[
            MinLengthValidator(650),
            MaxLengthValidator(2000)
        ])
        person_spec = models.TextField(default=None, validators=[
            MinLengthValidator(650),
            MaxLengthValidator(2000)
        ])
        salary = models.PositiveIntegerField(default=None, validators=[
            MinValueValidator(20000),
            MaxValueValidator(99000)
        ])
        city = models.CharField(choices=CITY_CHOICES, max_length=11, default=None)
        category = models.CharField(choices=CATEGORY_CHOICES, max_length=15, default=None)
        max_applications = models.PositiveSmallIntegerField(blank=True, null=True)
        deadline = models.DateField(default=None)
    
    
    class Application(models.Model):
        STAGES = [
            ('pre-selection', 'PRE-SELECTION'),
            ('shortlisted', 'SHORTLISTED'),
            ('rejected pre-interview', 'REJECTED PRE-INTERVIEW'),
            ('rejected post-interview', 'REJECTED POST-INTERVIEW'),
            ('successful', 'SUCCESSFUL')
        ]
        candidate = models.ForeignKey('Candidate', on_delete=models.CASCADE)
        job = models.ForeignKey('Vacancy', on_delete=models.CASCADE)
        cv = models.CharField(max_length=60, default=None)
        cover_letter = models.TextField(default=None, validators=[
            MinLengthValidator(0),
            MaxLengthValidator(2000)
        ])
        submitted = models.DateTimeField(auto_now_add=True)
        stage = models.CharField(choices=STAGES, max_length=25, default='pre-selection')
        vacancy = models.ForeignKey(Vacancy, related_name='applications', on_delete=models.DO_NOTHING)
    

    【讨论】:

    • 但是如果我需要它来保持ManyToManyField 的身份怎么办?有没有办法确保我的Vacancy 表上的每个application 只链接到一个......比如说city(字符域)?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    • 2011-04-28
    • 1970-01-01
    相关资源
    最近更新 更多