Why cannot use 2 separate foreign keys for same mo

2019-07-24 13:00发布

问题:

I have a theoretical model that isn't working:

class Message(models.Model):
       text = models.TextField()
       created = models.DateTimeField(auto_now_add=True)
       sender = models.ForeignKey(User)
       receiver = models.ForeignKey(User)

Now if a user messaged someone, like a private message thread, you have someone who sent it, and someone who received it, which is important to know. Both of these should be a one-to-many I think because each user can send infinite messages. Senders and receivers are users, from the same model User, but they must be different people. I get django whining about

django.core.management.base.CommandError: System check identified some issues:

ERRORS:
chat.Message.receiver: (fields.E304) Reverse accessor for 'Message.receiver' clashes with reverse accessor for 'Message.sender'.
    HINT: Add or change a related_name argument to the definition for 'Message.receiver' or 'Message.sender'.
chat.Message.sender: (fields.E304) Reverse accessor for 'Message.sender' clashes with reverse accessor for 'Message.receiver'.
    HINT: Add or change a related_name argument to the definition for 'Message.sender' or 'Message.receiver'.

Should I add unique=True since you can't send messages to yourself? Is this a bad way to implement messages between users? And what is my error? Thank you,

Cody

回答1:

As the error message says add the related_name argument to the foreign key definitions:

class Message(models.Model):
    text        = models.TextField()
    created     = models.DateTimeField(auto_now_add=True)
    sender      = models.ForeignKey(User, related_name='messages_sent')
    receiver    = models.ForeignKey(User, related_name='messages_received')

These related names can be used in the backward relations like this:

user = User.objects.get(username='johndoe')
messages_from = user.messages_sent.all()
messages_to = user.messages_received.all()

Which is the equivalent of:

user = User.objects.get(username='johndoe')
messages_from = Messages.objects.filter(sender=user)
messages_to = Messages.objects.filter(receiver=user)