首页 > 解决方案 > 如何验证 Django Rest Framework 中是否存在具有特定参与者(多对多字段)的对话对象?

问题描述

模型.py

from django.contrib.auth.models import User
    
class Conversation(models.Model):
    participants = models.ManyToManyField(User, related_name="conversation")

网址.py

path('api/conversations/', views.ConversationListView.as_view(),
         name='conversation-list'),

序列化程序.py

class ConversationSerializer(serializers.ModelSerializer):
    participants = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(),
                                                      many=True)

    class Meta:
        model = Conversation
        fields = ['id', 'participants']

视图.py

class ConversationListView(APIView):   
    def get(self, request, format=None):
        conversations = Conversation.objects.all()
        serializer = ConversationSerializer(
            conversations, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = ConversationSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

所以我想用这个对象在“api/conversations/”上发出一个 POST 请求:

{"participants": [2,3]} or {"participants": [3,2]} 

但我想首先检查与参与者的对话是否同时存在用户(id = 2)和用户(id = 3)。如果存在,我需要提出一个错误。如果不存在,则创建一个新对话。所以 User(id=2) 和 User(id=3) 之间只有一次对话。

到目前为止我所知道的是我必须在序列化程序中制作validate_participants(self, value) 。但我仍然无法弄清楚检查它的逻辑是什么。我试过使用Conversation.objects.filter(participants__in=[2,3])但我认为它不起作用,因为它不会返回同时具有 User(id=2) 和 User(id=3) 的对话对象) 作为参与者。

标签: pythondjangodjango-rest-framework

解决方案


这段代码解决了我的问题。将此添加到 ConversationSerializer

def validate_participants(self, value):
    query1 = Conversation.objects.filter(participants=value[0])
    query2 = Conversation.objects.filter(participants=value[1])

    if query1.intersection(query2).exists():
        raise serializers.ValidationError(
            "Conversation with these participants has exist")
    return value

推荐阅读