我正在尝试创建一个代表两个用户(只有两个)之间对话的Model
。
无法弄清楚如何创建两个字段,因为用户是等效的。
class Conversation(models.Model):
user_one = ForeignKey('auth.User')
user_two = ForeignKey('auth.User')
class Meta:
unique_together = ('user_one','user_two')
这是我设计模型的最佳方式吗?
然后是经理方法:
def get_conversation(user_one,user_two):
c = Conversation.objects.filter(Q(user_one=user_one,user_two=user_two)|Q(user_one=user_one,user_two=user_two))
return c
或者有更舒适的方式来处理这种模式吗?例如,使用ManyToManyField
并检查是否有两个且只有两个用户?:
users = ManyToManyField('auth.User')
答案 0 :(得分:0)
如果同一型号有多个外键,请使用related_name
字段。因为您通常不关心谁具体是user_one和user_two,所以您只需确保user_one和user_two是一致的。在这种情况下,我使用用户的id字段来说明哪个用户将是user_one,哪个用户将是user_two。这使得查询更简单,因为您不需要对两对(A,B)和(B,A)进行查询
class Conversation(models.Model):
user_one = ForeignKey('auth.User', related_name="user_one")
user_two = ForeignKey('auth.User', related_name="user_two")
class Meta:
unique_together = ('user_one','user_two')
def clean(self):
# Ensure that user_one's id is always less than user_two's
if self.user_one and self.user_two and self.user_one.id > self.user_two.id:
(self.user_one, self.user_two) = (self.user_two, self.user_one)
@classmethod
def get(cls, userA, userB):
""" Gets all conversations between userA and userB
"""
if userA.id > userB.id:
(userA, userB) = (userB, userA)
return cls.objects.filter(user_one=userA, user_two=userB)
答案 1 :(得分:0)
如果您使用的是postgres,可以使用ArrayField:
class Conversation(models.Model):
users = ArrayField(
ForeignKey('auth.User'),
size=2,
)
这有助于查找。但请注意文档目前关于size
参数的说明:
这是一个可选参数。如果传递,则数组将具有指定的最大大小。这将被传递到数据库,尽管PostgreSQL目前没有强制执行限制。