一个表不能外键给别人,除了一个表

例如一个表不能外键给别人,除了一个表

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级别执行此操作。对于你的结构,你应该在创建(或修改)BusyReserved之前添加一些验证。喜欢的东西:

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)

如果要创建BusyReserved对象同时它受到的竞争条件。我建议将房间状态移入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

回到顶部