【问题标题】:Resolving a three-way circular reference in SQL (Django)解决 SQL (Django) 中的三向循环引用
【发布时间】:2012-03-21 14:02:48
【问题描述】:

目前我在 Django 中有三个创建循环引用的模型:

User 可以住在Location 中。 Location 必须是 Property 的一部分。 Property 必须有一个所有者,即 User

我希望每个User 指定一个位置的原因是为住在公寓里的人。一个公寓租户会住在一个编号的房间里,但一个房子租户不会。但请注意,该位置也可以只是一个财产(即房屋租户居住的位置只是具有地址的财产;该财产没有房间号、楼层或建筑物。)。

这是(精简的)代码:

class User( models.Model ) :
    TYPE_CHOICES = (
        ( 't', 'tenant'           ),
        ( 'o', 'property owner'   ),
        ( 'v', 'vendor'           ),
        ( 'm', 'property manager' ),
    )

    user_type  = models.CharField( max_length = 1, choices = TYPE_CHOICES, default = 't' )
    first_name = models.CharField( max_length = 135 )
    last_name  = models.CharField( max_length = 135 )
    location   = models.ForeignKey( Location, null = True, blank = True )

class Property( models.Model ) :
    name             = models.CharField( max_length = 135 )
    owner            = models.ForeignKey( User )
    address_line_one = models.CharField( max_length = 135 )
    address_line_two = models.CharField( max_length = 135, blank = True )
    city             = models.CharField( max_length = 135 )
    state            = models.CharField( max_length = 135 )
    zip_code         = models.CharField( max_length = 135 )

class Location( models.Model ) :
    room       = models.CharField( max_length = 135, blank = True )
    floor      = models.CharField( max_length = 135, blank = True )
    building   = models.CharField( max_length = 135, blank = True )
    prop       = models.ForeignKey( Property )

如果你们需要更多说明或代码,请告诉我。提前致谢!

【问题讨论】:

  • 也许只是改变它,让Locations 有一个occupant,而不是Users 有一个location
  • @Amber 好的,所以 Location 可以与居住者 (User) 建立多对多关系?
  • 其实一个User一次只能住一个Location,所以可以一对多吗???这对我来说没有意义,如果它是多对一的,那么我们又回到了循环引用......
  • 查看我的一对多答案。你也可以有多对多,没有循环路径。 (只需删除 Unique 约束)

标签: python sql django database-design


【解决方案1】:

就像the docs 说的那样,您可以使用字符串来指定要在关系中使用的应用程序和模型。

如果需要在尚未定义的模型上创建关系,可以使用模型的名称,而不是模型对象本身

【讨论】:

  • 感谢您的链接。像这样具有循环外键引用通常是一种好习惯吗?我理解对于这些类型的引用,一次引用需要是可选的(可以是 NULL)。如果这不是一个好的做法,那么对于我的情况,我应该如何解决这个问题有什么建议吗?
【解决方案2】:

表引用中的循环路径会使您陷入严重的问题,而这些问题可以通过棘手和繁琐的解决方案来解决(并非所有此类解决方案都适用于所有 DBMS)。

如果你想避免它们,你应该重新设计表格。可能的方法是删除 User -> Location 外键(这是唯一一个不是强制性的,用你的话来说:“A User can live in a Location”,其他使用“必须”)并为该(可选)关系制作一个单独的表。

class User( models.Model ) :
    TYPE_CHOICES = (
        ( 't', 'tenant'           ),
        ( 'o', 'property owner'   ),
        ( 'v', 'vendor'           ),
        ( 'm', 'property manager' ),
    )

    user_type  = models.CharField( max_length = 1
                                 , choices = TYPE_CHOICES, default = 't' )
    first_name = models.CharField( max_length = 135 )
    last_name  = models.CharField( max_length = 135 )

class UserLocation( models.Model ) :
    person          = models.ForeignKey( User )
    person.unique   = True 
    apartm_location = models.ForeignKey( Location )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 2011-02-13
    • 1970-01-01
    • 2015-02-13
    相关资源
    最近更新 更多