Django模型:两个用户之间的对话

时间:2017-11-20 16:52:02

标签: python django database postgresql django-models

我正在尝试创建一个代表两个用户(只有两个)之间对话的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') 

2 个答案:

答案 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目前没有强制执行限制。