英文:
Filter query to get chat messages among two friends?
问题
我正在尝试创建一个聊天 API,我已经构建了消息模型如下所示:
class ChatMessage(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name="user")
sender = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name="sender")
receiver = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name="receiver")
message = models.CharField(max_length=10000000000)
is_read = models.BooleanField(default=False)
date = models.DateTimeField(auto_now_add=True)
现在我正在尝试编写 API 视图来获取只属于我和我正在聊天的人的所有消息。
让我详细说明一下:假设Destiny正在给Sammy发短信,肯定会有很多消息是在我(Destiny)和用户(Sammy)之间发送的,所以我想获取所有这些消息。
这是我编写的用于此目的的视图:
class GetMessages(generics.ListAPIView):
serializer_class = MessageSerializer
def get_queryset(self):
sender_id = self.kwargs['sender_id']
receiver_id = self.kwargs['receiver_id']
messages = ChatMessage.objects.filter(sender=sender_id, receiver=receiver_id)
return messages
URL 路由:
path("api/get-messages/<sender_id>/<receiver_id>/", views.GetMessages.as_view()),
这是该视图返回的内容:
## URL - http://127.0.0.1:8000/api/get-messages/2/1/
[
{
"id": 2,
"sender": 2,
"receiver": 1,
"message": "Hey Destiny",
"is_read": false
}
]
如果我交换了 sender_id
和 receiver_id
,我会得到以下响应:
# URL - http://127.0.0.1:8000/api/get-messages/1/2/
[
{
"id": 1,
"sender": 1,
"receiver": 2,
"message": "Hello Sammy",
"is_read": false
},
{
"id": 3,
"sender": 1,
"receiver": 2,
"message": "This is another message for you sammy",
"is_read": false
}
]
我想要的是,当我在 URL 中传入发送者的 ID(1)和接收者的 ID(2)时,我希望得到像这样的响应,即这两个人之间的所有对话:
[
{
"id": 1,
"sender": 1,
"receiver": 2,
"message": "Hello Sammy",
"is_read": false
},
{
"id": 2,
"sender": 2,
"receiver": 1,
"message": "Hey Destiny",
"is_read": false
},
{
"id": 3,
"sender": 1,
"receiver": 2,
"message": "This is another message for you sammy",
"is_read": false
}
]
一些图片:
英文:
I am trying to create a chat api, i have structured the messages model to look like this
class ChatMessage(models.Model):
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name="user")
sender = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name="sender")
reciever = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name="reciever")
message = models.CharField(max_length=10000000000)
is_read = models.BooleanField(default=False)
date = models.DateTimeField(auto_now_add=True)
Now i am trying to write the API view to get all messages that belongs only to me and the person that i am chatting with.
Let me elaborate: Let's say Destiny is texting Sammy, there would definitely be alot of messages that have been sent between me (Destiny) and the user (Sammy), so i want to get all that text.
This is the view that i have written to do this
class GetMessages(generics.ListAPIView):
serializer_class = MessageSerializer
def get_queryset(self):
sender_id = self.kwargs['sender_id']
reciever_id = self.kwargs['reciever_id']
messages = ChatMessage.objects.filter(sender=sender_id, reciever=reciever_id)
return messages
urls
path("api/get-messages/<sender_id>/<reciever_id>/", views.GetMessages.as_view()),
This is what this view returns
## url - http://127.0.0.1:8000/api/get-messages/2/1/
[
{
"id": 2,
"sender": 2,
"reciever": 1,
"message": "Hey Destiny",
"is_read": false
}
]
if i swap the sender_id and reciever_id, this is the response i get
# url - http://127.0.0.1:8000/api/get-messages/1/2/
[
{
"id": 1,
"sender": 1,
"reciever": 2,
"message": "Hello Sammy",
"is_read": false
},
{
"id": 3,
"sender": 1,
"reciever": 2,
"message": "This is another message for you sammy",
"is_read": false
}
]
what i want is this, when i pass in the id of the sender (1) and id of the reciever (2) in the url, i want to get a response like this, which is all the conversaion that this two folks have had.
[
{
"id": 1,
"sender": 1,
"reciever": 2,
"message": "Hello Sammy",
"is_read": false
},
{
"id": 2,
"sender": 2,
"reciever": 1,
"message": "Hey Destiny",
"is_read": false
},
{
"id": 3,
"sender": 1,
"reciever": 2,
"message": "This is another message for you sammy",
"is_read": false
}
]
答案1
得分: 2
你可以在这里使用一个 Q
对象:
from django.db.models import Q
然后
messages = ChatMessage.objects.filter(
Q(sender=sender_id, receiver=receiver_id) |
Q(sender=receiver_id, receiver=sender_id)
)
另外,注意正确的拼写是 receiver
。
英文:
You can use a Q
object here:
from django.db.models import Q
then
messages = ChatMessage.objects.filter(
Q(sender=sender_id, reciever=reciever_id) |
Q(sender=reciever_id, reciever=sender_id)
)
As a side note, it's spelled receiver
.
答案2
得分: 0
你也可以使用这种方法,
messages = ChatMessage.objects.filter(
sender__in=[sender_id, reciever_id], reciever__in=[reciever_id, sender_id]
)
英文:
You can also use this method,
messages = ChatMessage.objects.filter(
sender__in=[sender_id, reciever_id], reciever__in=[reciever_id, sender_id]
)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论