Django - 一对一的关系,一端主要是 NULL,另一端不是 NULL



我正在使用Django和PostgreSQL编写简单的应用程序来管理家庭图书库,在那里我可以为借书的人提供许多借阅者档案(Borrower模型)。我有用户,他们可以自己借书,这样这本书就可以被用户的借阅者资料借出。

另一方面,管理员可以将书籍借给任何借阅者,甚至是未注册为用户的人。

所以我有几个MyUser s(顺便说一句,那个字段引用了Django的User)和许多Borrower,我想在它们之间创建一个一对一的关系,但是每个MyUser都必须引用一个唯一的Borrower,但是许多Borrower不会引用任何现有的MyUser(它们只能引用一个或没有, 或者换句话说,仅由一个用户引用或没有用户引用)。

我的问题是:如何以最佳方式建模?使用models.OneToOneFieldmodels.ForeignKey以及哪个模型应该引用哪个模型?

我可能会有很多借款人,他们没有用户帐户。

自然解决方案似乎在User模型中OneToOneField(Borrower, null=False)。但是,在根据借款人搜索用户时,我将不得不主要处理DoesNotExists异常,并且偶尔我会得到适当的结果。

我也可以制作ForeignKey(Borrower, unique=True, null=False) - 然后我将不得不检查具有单个元素或空的集合。

我可以两种方式ForeignKey

class Borrower(models.Model):
    # ...
    user = models.ForeignKey(MyUser, unique=True, null=True)
class MyUser(models.Model):
    # ...
    borrower = models.ForeignKey(Borrower, unique=True, null=False)

这隐式定义了关系,我可以轻松地以两种方式进行搜索,但它也会在数据库表中创建一个额外的冗余字段。

我现在可能只会坚持OneToOneField,但我想知道在这种情况下哪种方法最有意义。过程和缺点是什么?有没有替代的、更好的解决方案?

我会坚持OneToOneField;正如你所说,这是最自然的解决方案。

您提到的唯一缺点是borrower.user可能会引发DoesNotExist异常。如果你不喜欢这样,你总是可以定义自己的方法(或属性)来返回其他东西(如None)。像这样:

class MyUser(models.Model):
    borrower = models.OneToOneField(Borrower, null=False)
class Borrower(models.Model):
    @property
    def user(self):
        try:
            return self.myuser
        except DoesNotExist:
            return None
    @user.setter
    def user(self, user):
        self.myuser = user

最新更新