我正在用Django和PostgreSQL编写简单的应用程序来管理一个家庭图书馆,我可以为那些借书的人(Borrower
模型)提供许多借阅者资料。我有用户,他们可以自己借书,这样书就会被用户的借款人资料借用。
另一方面,管理员可以借书给任何借款人,甚至是未注册的用户。
所以我有一些MyUser
s(以及那个字段,顺便说一句,引用Django的User
)和许多Borrower
,我想创建一对一的关系它们之间,但每个MyUser
都引用一个唯一的Borrower
,但许多Borrower
不会引用任何现有的MyUser
(它们可以只引用一个或不引用,或者换句话说,只引用一个或没有用户)。
我的问题是:如何以最佳方式进行建模?使用models.OneToOneField
,models.ForeignKey
以及哪个模型应该引用哪个?
我可能会有很多借款人,他们没有用户帐户。
自然解决方案似乎是OneToOneField(Borrower, null=False)
模型中的User
。但是,当根据借款人搜索用户时,我将不得不主要处理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
,但我想知道在这种情况下哪种方法最有意义。什么是触发和缺点?还有其他更好的解决方案吗?
答案 0 :(得分:0)
我会坚持使用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