ManyToMany的独特组合

时间:2017-06-25 20:28:11

标签: django django-models

我尝试在给定时间内为玩家创建唯一的可用状态。这是代码:

class Player(models.Model):
  first_name = models.CharField(max_length=200)
  last_name = models.CharField(max_length=200)

class Hour(models.Model):
  date = models.DateTimeField()
  players = models.ManyToManyField(Player, blank=True,
                                   through='Availability')

class Availability(models.Model):
  player = models.ForeignKey(Player, on_delete=models.CASCADE)
  hour = models.ForeignKey(Hour, on_delete=models.CASCADE)
  available = models.BooleanField()

我的问题是,它目前几次可以添加相同的可用性 - 我想以编程方式将其限制为每个组合只有一个。

提前致谢!

3 个答案:

答案 0 :(得分:4)

您可以在“ throuh”表(在您的情况下为“可用性表”)上具有unique_together

class Availability(models.Model):
  player = models.ForeignKey(Player, on_delete=models.CASCADE)
  hour = models.ForeignKey(Hour, on_delete=models.CASCADE)
  available = models.BooleanField()  
  class Meta:
    unique_together = (('player','hour'),)

然后使用get_or_create进行添加/修改:

 obj,created = Availability.objects.get_or_create(hour=hour,player=player)

答案 1 :(得分:1)

我一直在修改save()的{​​{1}}:

Availability

答案 2 :(得分:1)

unique中的ManyToManyField约束,ticket 702中的推理。您可以做的是在保存时验证模型,如an online snippet

所示
class MyModel(models.Model):
    site = models.ManyToManyField(Site)
    on_site = CurrentSiteManager()

    foobar = ... # A unique field

    def save(self, *args, **kwargs):
        if self.id == None: # new item should be created.
            # manually check a unique togeher, because django can't do this with a M2M field.
            # Obsolete if unique_together work with ManyToMany: http://code.djangoproject.com/ticket/702
            exist = MyModel.on_site.filter(foobar=self.foobar).count()
            if exist != 0:
                from django.db import IntegrityError
                # We can use attributes from this model instance, because it needs to have a primary key
                # value before a many-to-many relationship can be used.
                site = Site.objects.get_current()
                raise IntegrityError(
                    "MyModel item with same foobar field exist on site %r" % site
                )

        return super(MyModel, self).save(*args, **kwargs)

    class Meta:
        #unique_together = ("foobar", "site") # unique_together doesn't work with ManyToMany!
        # See: http://code.djangoproject.com/ticket/702

请注意,逻辑可能会根据您的目标而改变。正如Carl Meyer在上面链接的故障单中所说,不同的行为在您的模型中是有意义的(例如,ManyToManyField的每个项目或具有确切组合的字段是唯一的。)