Django List Serializer 批量更新失败,"QuerySet"对象没有属性&quo



我正在尝试使用ListSerializer进行批量更新Viewset.我的批量创建工作正常,但不是 PUT。这是我SerializerListSerizlier和我的观点。

django=2.0.0

Serializer

class SampleListSerializer(serializers.ListSerializer):
pass
class SampleSerializer(serializers.ModelSerializer):
class Meta:
list_serializer_class = SampleListSerializer
model = Sample
fields = ['id', 'name', 'last_name' ]

这是我的ViewSet


class SampleViewSet(viewsets.ModelViewSet):
serializer_class = SampleSerializer
queryset = Sample.objects.all()
def get_serializer(self, *args, **kwargs):
if "data" in kwargs:
data = kwargs["data"]
# check if many is required
if isinstance(data, list):
kwargs["many"] = True
return super(SampleViewSet, self).get_serializer(*args, **kwargs)
def put(self, request):
sorted(request.data, key=lambda o: o["id"])
instances = Sample.objects.filter(id__in=[o["id"] for o in request.data]).order_by("id")
try:
with transaction.atomic():
ss = SampleSerializer(data=request.data, instance=instances, many=True)
if ss.is_valid(raise_exception=True):
s = ss.save()
return Response(ss.data)
return Response(status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
print(f"In exception {e}")
return Response(status=status.HTTP_400_BAD_REQUEST)
def create(self, request, *args, **kwargs):
return super().create(request, *args, **kwargs)

我得到的"查询集"对象在ss.is_valid()没有属性"pk"。有人可以建议我的错误在哪里吗?还是怎么了?

>instance关键字采用单个 QuerySet 对象,但看起来您正在传递一个"ListQuerySet"(技术上只是一个 QuerySet(。

如果你print(instances)它将看起来像这样(假设你没有覆盖类的__str__方法(:

<QuerySet [<Sample: Sample object(1)>, <Sample: Sample object(2)>, ... ]>

serializers.ModelSerializer的某处,instance.pk被调用,这将始终导致:

"QuerySet"对象没有属性"pk">

这里有一个改编的答案:https://github.com/miki725/django-rest-framework-bulk/issues/68

最好的解决方法是 覆盖ListSerializer上的to_internal_value.

def to_internal_value(self, data):
"""
List of dicts of native values <- List of dicts of primitive datatypes.
"""
if html.is_html_input(data):
data = html.parse_html_list(data)
if not isinstance(data, list):
message = self.error_messages['not_a_list'].format(
input_type=type(data).__name__
)
raise ValidationError({
api_settings.NON_FIELD_ERRORS_KEY: [message]
}, code='not_a_list')
if not self.allow_empty and len(data) == 0:
if self.parent and self.partial:
raise SkipField()
message = self.error_messages['empty']
raise ValidationError({
api_settings.NON_FIELD_ERRORS_KEY: [message]
}, code='empty')
ret = []
errors = []
for item in data:
try:
# custom code
self.child.instance = self.instance.get(id=item['id']) if self.instance else None
self.child.initial_data = item
validated = self.child.run_validation(item)
except ValidationError as exc:
errors.append(exc.detail)
else:
ret.append(validated)
errors.append({})
if any(errors):
raise ValidationError(errors)
return ret

相关内容

最新更新