Django-如何映射用户之间发送的消息

时间:2015-12-07 01:07:30

标签: python mysql django database orm

我正在为应用实现一项功能,让用户能够向其他用户发送活动邀请。邀请本身需要能够获得关于在活动中执行的组的信息,关于活动本身的信息(即日期/时间,地点,位置)以及关于发送者和接收者的信息。来自使用PHP工作的数据库,我会更简单地考虑为邀请创建一个数据库表,其中包含事件的id,组的id,发件人和收件人的用户ID,以及与它一起发送的消息。这个结构使得所有邀请都存储在同一个表中,每当用户想要检查他们的邀请时,应用程序将查询该表以查找具有其id的所有行。

问题是,对于一个,django使用的模型(我还没有真正习惯使用),每次创建一个对象时都会隐式设置id。除此之外,因为我正在为django提供的用户使用内置模型,所以我不确定如何在创建invites表时调用用户模型。我的另一个想法是扩展Django的用户模型,添加一个many to many field,它将为收件人和发件人(都是类型用户)添加外键,这将是我理解的后向相关对象。然而,Django文档建议不要这样做,所以我认为这不是构建邀请表的最佳方法。

我应该如何构建此功能?任何帮助将不胜感激。

以下是我对invites表的当前实现(它返回了相关name属性的名称错误):

 class User(AbstractBaseUser):
    email = models.EmailField()
    # full_name = models.CharField(max_length = 120, blank = True, null = True)
    user_name = models.CharField(max_length = 40, unique =True)
    USERNAME_FIELD = "user_name"
    REQUIRED_FIELDS = ['email']
    timestamp = models.DateTimeField(auto_now_add = True, auto_now = False)
    updated = models.DateTimeField(auto_now_add = False, auto_now = True)
    invites = models.ManyToManyField(
        'self', through = 'Invite', 
        symmetrical = False )

    def __unicode__(self):
        return self.full_name

    def get_full_name():
        return self.



 class Invite(models.Model):
    sender_id = models.ForeignKey(User, related_name= invite_sender, on_delete = models.CASCADE )
    recipient_id = models.ForeignKey(User, related_name= invite_recipient, on_delete = models.CASCADE)
    concert_id = models.AutoField()
    artist_id = models.AutoField()
    message = models.CharField(max_length = 120, blank = True, null = True)
    date_sent = models.DateTimeField(auto_now_add = True, auto_now = False)

2 个答案:

答案 0 :(得分:1)

好的,所以这本来是一个评论,但我跑过了角色限制。

音乐会和艺术家都应该是ForeignKey的独立模特。发件人和收件人应该是ForeignKey的用户模型。您是否故意尝试存储ID而不是实际存储的内容?在Django中,您不希望存储发件人ID并在需要时使用它执行查找。相反,您只想从一开始就将ForeignKey链接到它,然后直接从中获取信息。

同样在您的用户字段中,我不一定知道用户有必要跟踪自己的邀请。您似乎正在将ManyToMany攻击到OneToMany中,因此您可以在必要时通过发件人或收件人ID查找邀请,这可能会更清晰。现在的方式是你必须确保你向用户添加所有邀请,并且我总是担心你必须有一个对象不断声称拥有另一个对象的任何情况。例如,如果您不小心创建了可以创建邀请而无需将其分配给用户的代码,那么您将有邀请卡在以太网中。只需在运行时查看相关邀请就可以避免这种情况。

我建议您阅读使用对象关系映射(ORM),以便整个过程更有意义。

答案 1 :(得分:1)

related_name的问题是它应该是一个字符串,如下所示:

sender_id = models.ForeignKey(User, related_name= 'invites_sent', on_delete = models.CASCADE )
recipient_id = models.ForeignKey(User, related_name= 'invites_received', on_delete = models.CASCADE)

这解决了获取用户邀请的问题,因为这是相关名称的用途。假设您有一个用户实例化为此用户,您可以通过以下方式获取他发送的所有邀请:

invites = thisuser.invites_sent.all()

或者他收到的邀请:

invites = thisuser.invites_received.all()

也许有一个我不了解的目的,因为我对这一切都很陌生,但我没有看到concert_id中的重点。 artist_id字段,因为它们都是auto_field并且总是具有相同的值,这也是id字段的相同值,正如您所指出的那样out,django自动创建(当你没有将另一个字段设置为模型的主键时)。

我要做的是以下内容。如此定义邀请:

class Invite(models.Model):
    sender = models.ForeignKey(User, related_name= 'invites_sent', on_delete = models.CASCADE )
    recipient = models.ForeignKey(User, related_name= 'invites_received', on_delete = models.CASCADE)
    message = models.CharField(max_length = 120, blank = True, null = True)
    date_sent = models.DateTimeField(auto_now_add = True, auto_now = False)

然后你可以创建这样的新邀请:

from appname.models import User, Invite

inviter = User.objects.get(id=57) #enter whatever id is the inviter's id
invitee = User.objects.get(id=42) #enter id of person that is being invited
new_invite = Invite(sender=inviter, recipient=invitee, message='Hello, you are invited')
new_invite.save()

并让用户邀请如下:

from appname.models import User, Invite

thisuser = User.objects.get(id=42)
invites_sent_by_user = thisuser.invites_sent.all()
invites_received_by_user = thisuser.invites_received.all()
invites_received_after_march_seventh= thisuser.invites_received.filter(date_sent__gt='2015-03-07')

由于您可以通过外键声明中指定的related_name访问邀请,因为用户模型上的manytomanyfield没有用处。

希望我涵盖了大部分内容

(因为我输入了所有代码,可能会出现拼写错误)