【问题标题】:Getting objects before validating data Django REST在验证数据 Django REST 之前获取对象
【发布时间】:2022-08-08 00:29:42
【问题描述】:

我必须使用此视图创建一个新的 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 中获取对象?

    标签: python django django-rest-framework django-serializer


    【解决方案1】:

    我认为您需要在序列化程序中添加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
        ]
    }
    

    【讨论】:

    • 感谢你的回答!跟进:我必须进行此转换的事实是否表明我正在错误地构建我的业务逻辑?
    【解决方案2】:

    您好大卫,您可以利用在序列化程序中覆盖 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 方法之前调用。

    【讨论】:

      猜你喜欢
      • 2016-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-13
      • 2013-02-17
      • 2017-03-09
      • 2012-07-28
      • 1970-01-01
      相关资源
      最近更新 更多