一个表不能外键给别人,除了一个表
例如一个表不能外键给别人,除了一个表
class Room(models.Model): visitor = models.ForeignKey(Visitor)
number = models.PositiveIntegerField()
capacity = models.ForeignKey(Capacity, on_delete=models.PROTECT)
floor = models.ForeignKey(Floor, on_delete=models.PROTECT)
price = models.PositiveIntegerField()
is_premium = models.BooleanField(default=False)
is_vip = models.BooleanField(default=False)
expiry_date = models.DateTimeField()
class Meta:
unique_together = ('')
def __str__(self):
return '№{0}'.format(self.number)
class Reserved(models.Model):
room = models.ForeignKey(Room)
begin_date = models.DateTimeField()
def __str__(self):
return 'Reserved Room {0}'.format(self.room)
class Busy(models.Model):
room = models.ForeignKey(Room)
表间无法连接到表保留,并在同一时间忙。房间应保留或忙碌。有没有办法对此进行验证? 我试图用unique_together但是如果表中的字段
感谢
回答:
没有办法在数据库级别,也不是简单的方法来做到这一点在Django级别执行此操作。对于你的结构,你应该在创建(或修改)Busy
和Reserved
之前添加一些验证。喜欢的东西:
class Busy(models.Model): room = models.ForeignKey(Room)
def __save__(self, *args, **kwargs):
if Reserved.object.filter(room=self.room).exists():
raise RuntimeError('Trying to make a reserved room busy.')
super(Busy, self).__save__(*args, **kwargs)
如果要创建Busy
和Reserved
对象同时它受到的竞争条件。我建议将房间状态移入Room
模型本身并添加一些辅助函数(类似旁边的room_manager.py
)以更改其状态并确保以一致的方式创建/修改相关模型。
回答:
确保在数据库级别你有一个单一的“身份”在给定的时间,一个房间是有你的关系,反过来想,唯一的方法 - 用Room
有一个外键上的任何代表状态。为了完成这个工作,你需要使用某种形式的模型继承或者django的“通用”关系(它可能有时候很方便但实际上不适合SQL)。
这是一个使用“模型继承”(这实际上不是继承的话)的最简单形式的例子:
class Status(models.Model): BUSY = 1
RESERVED = 2
TYPES = (
(BUSY,"busy"),
(RESERVED,"reserved")
)
type = models.CharField("Status type", max_length=10, choices=TYPES)
# only used for reservations
begin_date = models.DateTimeField(null=True, blank=True)
def save(self, *args, **kw):
# TODO : this should belong to `full_clean()`,
# cf the FineManual model's validation
if self.type == self.RESERVED and not self.begin_date:
raise ValueError("RESERVED statuses need a begin_date")
super(Status, self).save(*args, **kw)
class Room(models.Model):
status = models.ForeignKey(Status)
注意,这允许相同的状态,以用于在多个房间同时,这也可能是一个问题。使用OneToOneField
字段可能有助于Django方面,但仍将在数据库级别作为外键处理。
以上是 一个表不能外键给别人,除了一个表 的全部内容, 来源链接: utcz.com/qa/263352.html