与ManyToManyField相关的自定义唯一字段

时间:2012-10-04 12:28:20

标签: django django-models

让我们从模型开始

#models.py
class Project(models.Model):
    owner = models.ForeignKey(User)
    name = models.CharField(max_length=100)

class Issue(models.Model):
    project = models.ForeignKey(Project)
    title = models.CharField(max_length=100)
    status = models.ForeignKey('Status')


class Status(models.Model):
    name= models.CharField(max_length=10, help_text=u'eg open, closed...')
    default = models.BooleanField(default=False)
    project = models.ManyToManyField(Project)

    def save(self, *args, **kwargs):
        if self.default:
            #self.__class__.objects.filter(default=True, project=self.project).update(default=False)
            pass

当用户选择另一个default False选项时,我想将所有Status设置为default。我怎么能做到这一点?

修改

用户可以为他的项目创建自定义Status。所以,假设用户有2个项目 - 他们被称为奥迪宝马

现在,用户为Status创建Issue。它的名称将为open,并且他会将其选为Issues 宝马中所有Project的默认值。 项目 BMW 中的所有问题都将获得默认状态open。太好了!

现在,用户为Status创建了另一个Issue。这次名称为new,他将其选为默认所有项目

因此,我需要的是(尽可能减少查询)将 BMW 中的第一个状态open设置为default = false

2 个答案:

答案 0 :(得分:1)

您可以使用ForeignKey Status关系创建单实例设置模型:

class Settings(models.Model):
    default_status = models.ForeignKey('Status')

您可能希望enforce只有一个Settings实例。

或者,您可以在save()中执行取消默认:

if self.default:
    for status in self.__class__.objects.all():
        if status != self:
            status.default = False
            status.save()

请注意,如果您要覆盖Model.save(),则需要使用super()来重新启动该功能的原始行为。请参阅Django文档中的Overriding predefined model methods

答案 1 :(得分:1)

    def save(self, *args, **kwargs):
        if self.default:
            for status in Status.objects.filter(default=True,project__in=self.project.all()):
                status.default=False
                status.save()
        super(Status,self).save(*args,**kwargs)