代码之家  ›  专栏  ›  技术社区  ›  Eric Acevedo

在子类唯一\u together元选项中使用基类字段时出错

  •  8
  • Eric Acevedo  · 技术社区  · 14 年前

    使用以下代码:

    class Organization(models.Model):
        name = models.CharField(max_length="100",)
        alias = models.SlugField()
        ...
    
    class Division(Organization):
        parent_org = models.ForeignKey(Organization)
    
        class Meta:
            unique_together=['parent_org', 'alias']
            ...
    

    尝试同步数据库时出错:

    Error: One or more models did not validate:
    organizations.division: "unique_together" refers to alias. This is not in the 
    same model as the unique_together statement.
    

    感谢您的帮助,

    谢谢,

    埃里克

    4 回复  |  直到 11 年前
        1
  •  13
  •   Pewpewarrows    14 年前

    unique_together

    [field]_ptr_id [field] organization_ptr_id

    unique_together UNIQUE

    Validators

    Model Validators validate_unique

        2
  •  4
  •   Jameson Quinn    14 年前

    class BaseOrganization(models.Model):
        name = models.CharField(max_length="100",)
        alias = models.SlugField()
        class Meta:
            abstract = True
    
    class Organization(BaseOrganization):
        pass
    
    class Division(BaseOrganization):
        parent_org = models.ForeignKey(Organization)
    
        class Meta:
            unique_together=['parent_org', 'alias']
    

        3
  •  2
  •   Richard    11 年前

    unique_together

    class Meta():
        abstract = True
    

    单桅帆船 可能是因为所有字段都在同一个表中。

    https://docs.djangoproject.com/en/1.5/topics/db/models/#abstract-base-classes

        4
  •  1
  •   user2994322    11 年前

    这是我最近在Django 1.6中使用的解决方案(感谢Manoj Govindan的想法):

    class Organization(models.Model):
        name = models.CharField(max_length="100",)
        alias = models.SlugField()
        ...
    
    class Division(Organization):
        parent_org = models.ForeignKey(Organization)
    
        # override Model.validate_unique
        def validate_unique(self, exclude=None):     
            # these next 5 lines are directly from the Model.validate_unique source code
            unique_checks, date_checks = self._get_unique_checks(exclude=exclude)
            errors = self._perform_unique_checks(unique_checks)
            date_errors = self._perform_date_checks(date_checks)
            for k, v in date_errors.items():
                errors.setdefault(k, []).extend(v)
    
            # here I get a list of all pairs of parent_org, alias from the database (returned 
            # as a list of tuples) & check for a match, in which case you add a non-field 
            # error to the error list
            pairs = Division.objects.exclude(pk=self.pk).values_list('parent_org', 'alias')
            if (self.parent_org, self.alias) in pairs:
                    errors.setdefault(NON_FIELD_ERRORS, []).append('parent_org and alias must be unique')
    
            # finally you raise the ValidationError that includes all validation errors, 
            # including your new unique constraint
            if errors:
                raise ValidationError(errors)