对于DRF中与中间模型的多对多关系的序列化,我有一个很大的问题:如果请求方法是get everything,那么一切都可以正常工作。但是,只要我尝试向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, *args, **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, *args, **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.
我不太清楚如何编写正确的创建和更新函数,我也不太明白,文档中是如何解释的。
代码:
视图.py:
from django.shortcuts import render
from django.contrib.auth.models import User, Group
from 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_dict
class OrderSetDetails(generics.RetrieveUpdateDestroyAPIView):
queryset = Order.objects.all()
serializer_class = OrderSerializer
class OrderSetList(generics.ListCreateAPIView):
queryset = Order.objects.all()
serializer_class = OrderSerializer
class EquipmentSetDetails(generics.RetrieveUpdateDestroyAPIView):
queryset = Equipment.objects.all()
serializer_class = EquipmentSerializer
class EquipmentSetList(generics.ListCreateAPIView):
queryset = Equipment.objects.all()
serializer_class = EquipmentSerializer
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all().order_by('-date_joined')
serializer_class = UserSerializer
class GroupViewSet(viewsets.ModelViewSet):
queryset = Group.objects.all()
serializer_class = GroupSerializer
class ClientList(generics.ListCreateAPIView):
queryset = client.objects.all()
serializer_class = ClientSerializer
序列化程序.py
from rest_framework import serializers
from django.contrib.auth.models import User, Group
from 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 = User
fields = ('url', 'username', 'email', 'groups')
class GroupSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Group
fields = ('url', 'name')
class OrderSerializer(serializers.ModelSerializer):
class Meta:
model = Order
fields = '__all__'
型号.py:
from __future__ import unicode_literals
from 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.name
class 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, blank = True, null = True)
status = models.CharField(max_length=30, choices=order_choices, default='glyphicon glyphicon-remove')
def __str__(self):
return self.name
class Assignment(models.Model):
Equipment = models.ForeignKey('Equipment', on_delete=models.CASCADE)
Order = models.ForeignKey('Order', on_delete=models.CASCADE)
quantity = models.PositiveIntegerField(default=1)
提前谢谢。
我认为错误的原因:
JSON parse error - No JSON object could be decoded
是因为您忘记将.data
放在@Ivan Semochkin solution:representation['assigment'] = AssignmentSerializer(instance.assigment_set.all(), many=True).data
的第二行。因此,我发现我将偶然发现
Keyword Error: 'event'
from line:representation = super(EquipmentSerializer, self).to_representation(instance)
,因为equipmentserializer对象包含中介assignment_set
,而不是event
。以下是我所做的@Ivan Semochkin解决方案的最终结果。如果我在实践中错了/不合适,请纠正我。
如果我错了,请纠正我。我是新来的。
DRF不支持嵌套序列化程序的
create
方法。如果要在扩展布局中显示相关字段,而不仅仅是pks,则可以重写to_representation
方法,而不是重写默认的mtm
字段。您还应该重写create
方法,因为mtm
链接中有第三个模型:现在它将正确地保存传递pks列表的mtm字段,比如
[1, 2, 3]
,并且为了表示与mtm相关的模型,EquipmentSerializer
将使用AssignmentSerializer
。相关问题 更多 >
编程相关推荐