在验证数据 Django REST 之前获取对象

Getting objects before validating data Django REST

我必须使用此视图创建一个新的 Chat 对象:

class ChatListCreateView(ListCreateAPIView):
    permission_classes = [IsAuthenticated]
    serializer_class = ChatSerializer

    def get_queryset(self):
        data = Chat.objects.filter(
            Q(employees=self.request.user) | Q(created_by=self.request.user)).distinct()
        return data

它使用的序列化器是:

class ChatSerializer(serializers.ModelSerializer):
    created_by = SimpleEmployeeSerializer(read_only=True)
    employees = SimpleEmployeeSerializer(many=True, read_only=True)
    title = serializers.CharField(max_length=255)

    def create(self, validated_data):
        """
        Creates a new Chat and adds the m2m employees to it
        """
        # Create and save the chat
        chat = Chat.objects.create(
            created_by=self.context['request'].user,
            title=validated_data['title'],
        )

        # Add the employees to the chat
        validated_employees = validated_data.pop('employees')
        for user_id in validated_employees:
            employee = Employee.objects.get(id=user_id)
            chat.employees.add(employee)

        return chat

我的问题是 SimpleEmployeeSerializer 需要一个 user 对象,但我提交了一个 employees 的数组:

{
    "title": "fwef",
    "employees": [
        {
            "id": "8"
        },
        {
            "id": "30"
        }
    ]
}

我可以采用什么方法在验证之前从这些 ID 中获取对象?

你好大卫,你可以利用重写序列化程序中的 validate 方法,你必须执行如下操作:

class ChatSerializer(serializers.ModelSerializer):
    created_by = SimpleEmployeeSerializer(read_only=True)
    employees = SimpleEmployeeSerializer(many=True, read_only=True)
    title = serializers.CharField(max_length=255)
    
    def validate_employees(self, value):
        value= transform_ids_in_objects(value) 
        # handle validation logic here 
        return value

    def create(self, validated_data):
        chat = Chat.objects.create(
            created_by=self.context['request'].user,
            title=validated_data['title'],
        )
        # ... More code here
        return chat

Documentation about validate method 关于 validate 方法的重要一点是这个方法在 create 方法之前被调用。

我认为您需要在序列化程序中添加 employee_ids 字段。

class ChatSerializer(serializers.ModelSerializer):
    created_by = SimpleEmployeeSerializer(read_only=True)
    employees = SimpleEmployeeSerializer(many=True, read_only=True)        
    title = serializers.CharField(max_length=255)
    employee_ids = serializers.ListField(
        child=serializers.IntegerField(), write_only=True
    )

def create(self, validated_data):
    """
    Creates a new Chat and adds the m2m employees to it
    """
    employee_ids = validated_data.pop("employee_ids")

    # Create and save the chat
    chat = Chat.objects.create(
        created_by=self.context['request'].user,
        title=validated_data['title'],
    )

    # Add the employees to the chat one by one
    for user_id in employee_ids:
        try:
            employee = Employee.objects.get(id=user_id)
            chat.employees.add(employee)
        except Employee.DoesNotExist:
            continue
    
    # Or you can add multiple objects at once
    # chat.employees.set(employee_ids)

    return chat

并且您可以按如下方式上传json数据。

{
    "title": "fwef",
    "employees": [
        8, 30
    ]
}