默认情况下,.create()方法不支持可写的嵌套字段。

浏览:28日期:2024-03-06
如何解决默认情况下,.create()方法不支持可写的嵌套字段。?

DRF不支持create嵌套序列化器的方法。如果要以扩展布局显示相关字段,而不仅是pks,还可以覆盖该to_representation方法,而不必重写默认mtm字段。您还应该重写create方法,因为mtm链接中有第三个模型:

class EquipmentSerializer(serializers.ModelSerializer): class Meta: model = Equipment fields = ’__all__’ def create(self, validated_data):order = Order.objects.get(pk=validated_data.pop(’event’))instance = Equipment.objects.create(**validated_data)Assignment.objects.create(Order=order, Equipment=instance)return instance def to_representation(self, instance):representation = super(EquipmentSerializer, self).to_representation(instance)representation[’assigment’] = AssignmentSerializer(instance.assigment_set.all(), many=True).datareturn representation

现在,它将保存正确传递pk列表的mtm字段,例如[1, 2,3]和用于表示该mtm相关模型的,EquipmentSerializer将使用AssignmentSerializer。

解决方法

关于在DRF中与中间模型进行多对多关系的序列化,我遇到了一个大问题:如果请求方法得到了,那么一切都将正常运行。但是,一旦我尝试将数据发布或放置到API中,就会出现以下错误:

Traceback (most recent call last): File '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/handlers/base.py',line 149,in get_response response = self.process_exception_by_middleware(e,request) File '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/handlers/base.py',line 147,in get_response response = wrapped_callback(request,*callback_args,**callback_kwargs) File '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/views/decorators/csrf.py',line 58,in wrapped_view return view_func(*args,**kwargs) File '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/views/generic/base.py',line 68,in view return self.dispatch(request,*args,**kwargs) File '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/djangorestframework-3.5.3-py2.7.egg/rest_framework/views.py',line 477,in dispatch response = self.handle_exception(exc) File '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/djangorestframework-3.5.3-py2.7.egg/rest_framework/views.py',line 437,in handle_exception self.raise_uncaught_exception(exc) File '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/djangorestframework-3.5.3-py2.7.egg/rest_framework/views.py',line 474,in dispatch response = handler(request,**kwargs) File '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/djangorestframework-3.5.3-py2.7.egg/rest_framework/generics.py',line 243,in post return self.create(request,**kwargs) File '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/djangorestframework-3.5.3-py2.7.egg/rest_framework/mixins.py',line 21,in create self.perform_create(serializer) File '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/djangorestframework-3.5.3-py2.7.egg/rest_framework/mixins.py',line 26,in perform_create serializer.save() File '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/djangorestframework-3.5.3-py2.7.egg/rest_framework/serializers.py',line 214,in save self.instance = self.create(validated_data) File '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/djangorestframework-3.5.3-py2.7.egg/rest_framework/serializers.py',line 888,in create raise_errors_on_nested_writes(’create’,self,validated_data) File '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/djangorestframework-3.5.3-py2.7.egg/rest_framework/serializers.py',line 780,in raise_errors_on_nested_writes class_name=serializer.__class__.__name__AssertionError: The `.create()` method does not support writable nested fields by default.Write an explicit `.create()` method for serializer `manager.serializers.EquipmentSerializer`,or set `read_only=True` on nested serializer fields.

我不太确定如何编写适当的创建和更新函数,我也不是很了解它,它在文档中是如何解释的。

码:

views.py:

from django.shortcuts import render from django.contrib.auth.models import User,Groupfrom manager.serializers import *from rest_framework import generics from rest_framework import viewsets from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework.views import APIView from django.forms.models import model_to_dictclass OrderSetDetails(generics.RetrieveUpdateDestroyAPIView): queryset = Order.objects.all() serializer_class = OrderSerializerclass OrderSetList(generics.ListCreateAPIView): queryset = Order.objects.all() serializer_class = OrderSerializerclass EquipmentSetDetails(generics.RetrieveUpdateDestroyAPIView): queryset = Equipment.objects.all() serializer_class = EquipmentSerializerclass EquipmentSetList(generics.ListCreateAPIView): queryset = Equipment.objects.all() serializer_class = EquipmentSerializerclass UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all().order_by(’-date_joined’) serializer_class = UserSerializerclass GroupViewSet(viewsets.ModelViewSet): queryset = Group.objects.all() serializer_class = GroupSerializerclass ClientList(generics.ListCreateAPIView): queryset = client.objects.all() serializer_class = ClientSerializer

serializers.py

from rest_framework import serializers from django.contrib.auth.models import User,Groupfrom storage.models import *class AssignmentSerializer(serializers.HyperlinkedModelSerializer): id = serializers.ReadOnlyField(source = ’Order.id’) name = serializers.ReadOnlyField(source = ’Order.name’) class Meta:model = Assignment fields = (’id’,’name’,’quantity’)class EquipmentSerializer(serializers.ModelSerializer): event = AssignmentSerializer(source= ’assignment_set’,many = True) class Meta: model = Equipment fields = ’__all__’class ClientSerializer(serializers.ModelSerializer): class Meta: model = client fields = ’__all__’class UserSerializer(serializers.HyperlinkedModelSerializer): class Meta:model = Userfields = (’url’,’username’,’email’,’groups’)class GroupSerializer(serializers.HyperlinkedModelSerializer): class Meta:model = Groupfields = (’url’,’name’)class OrderSerializer(serializers.ModelSerializer): class Meta: model = Order fields = ’__all__’

models.py:

from __future__ import unicode_literalsfrom django.db import models from storage.choices import *# Create your models here.class Equipment(models.Model): name = models.CharField(max_length=30) fabricator = models.CharField(max_length=30,default=’-’) storeplace = models.IntegerField() labor = models.CharField(max_length=1,choices=labor_choices) event = models.ManyToManyField(’Order’,blank = True,through= ’Assignment’,through_fields=(’Equipment’,’Order’)) max_quantity = models.IntegerField(default=1,null = True) status = models.CharField(max_length=8,choices = STATUS_CHOICES,default = ’im Lager’) def __str__(self): return self.nameclass client(models.Model): firstname = models.CharField(max_length=30) secondname = models.CharField(max_length=30) email = models.EmailField() post_code = models.IntegerField() city = models.CharField(max_length=30) street= models.CharField(max_length=30) def __str__(self): return '%s %s' % (self.firstname,self.secondname)class Order(models.Model): name = models.CharField(max_length=30) Type = models.CharField(max_length=2,choices=TYPE_CHOICES,default=’Rental’,) city = models.CharField(max_length=30) street= models.CharField(max_length=30) date = models.DateField() GuestNumber = models.IntegerField() description = models.TextField() client = models.ForeignKey('client',on_delete=models.CASCADE,null = True) status = models.CharField(max_length=30,choices=order_choices,default=’glyphicon glyphicon-remove’) def __str__(self): return self.nameclass Assignment(models.Model): Equipment = models.ForeignKey(’Equipment’,on_delete=models.CASCADE) Order = models.ForeignKey(’Order’,on_delete=models.CASCADE) quantity = models.PositiveIntegerField(default=1)

提前致谢。

相关文章: