HTML 输入目前不支持列表

Lists are not currently supported in HTML input

我正在为我的 API 端点使用 Django REST 通用视图。我的序列化程序中的字段之一具有多对多关系。我想将该字段显示到我的 API 端点,但出现此错误

Lists are not currently supported in HTML input.

我的看法是这样的:

class AlertCreateView(ListCreateAPIView):
    permission_classes = (IsAuthenticated,)
    pagination_class = None
    serializer_class = AlertSerializer

    def get_queryset(self):
        queues = Queue.objects.all()
        for queue in queues:
           queryset = Alert.objects.filter(
               queue=queue
           )

        return queryset

我的序列化程序是这样的:

class AlertSerializer(serializers.ModelSerializer):
     queue = QueueSerializer(many=True)

     class Meta:
         model = Alert
         fields = (
             'id', 'name', 'queue','email', 'expected_qos'
         )

What can I do ?

没什么,因为 HTML 表单目前不支持嵌套序列化器。

您可以在序列化程序中使用非嵌套关系字段来解决这个问题,或者只使用常规 JSON.

您不需要 get_queryset 方法,您可以这样做:

#views.py
class AlertCreateView(ListCreateAPIView):
     queryset = Alert.objects.all()
     serializer_class = AlertSerializer
     permission_classes = (IsAuthenticated,)

序列化器中的 queues 字段的命名方式与在模型的 related_name 中的写入方式相同。你的 QueueSerializer 可以继承自 PrimaryKeyRelatedField 来渲染。

#models.py
class AlertModel(models.Model):
    ...
    queues = models.ManyToManyField(Queue, ... related_name='queues')     
    ...

#serializer.py
class QueueSerializer(PrimaryKeyRelatedField, serializers.ModelSerializer):
    class Meta:
       model: Queue

class AlertSerializer(serializers.ModelSerializer):
    queues = QueueSerializer(many=True, queryset=Queue.objects.all())

    class Meta:
        model = Alert
        fields = (
         'id', 'name', 'queues','email', 'expected_qos'
        )

您可以编写自己的 ListField class,并使用 style 参数在表单中输入文本。但是如果它来自表单,您还需要将值从文本转换为列表。

import json

class TextInputListField(serializers.ListField):

    def __init__(self, *args, **kwargs):
        style = {'base_template': 'input.html'}
        super().__init__(*args, style=style, **kwargs)

    def get_value(self, dictionary):
        value = super().get_value(dictionary)
        is_querydict = hasattr(dictionary, 'getlist')
        is_form = 'csrfmiddlewaretoken' in dictionary
        if value and is_querydict and is_form:
            try:
                value = json.loads(value[0])
            except Exception:
                pass
        return value

然后使用它代替通常的 ListField。