除一个表外,一个表不能是其他表的外键

时间:2017-12-18 12:34:26

标签: python django django-models

例如

listRoomsCall
.flatMap(v -> 
     Observable.fromIterable(v.getExchangeRoomList())
     .flatMap(exchangeRoom -> {
         mMeetingServiceApi.listMeetings(roomID, startsAtString, endsAtString, free);
     })
)
.subscribe(/* */);

Table Room无法同时连接到Tables Reserved和Busy。房间应该保留或忙碌。有没有办法对此进行验证? 我尝试使用unique_together但是如果是表

的字段

由于

2 个答案:

答案 0 :(得分:0)

无法在数据库级别强制执行此操作,也无法在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旁边的models.py)以更改其状态并确保在一个模型中创建/修改相关模型一致的方式。

答案 1 :(得分:0)

确保在数据库级的唯一方法是在给定时间内为一个房间提供一个“状态”是让您的关系反过来 - 使用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方有帮助,但在数据库级仍将被视为外键。