关于在DRF中与中间模型进行多对多关系的序列化,我遇到了一个大问题:如果请求方法是get,那么一切都可以正常运行。但是,一旦我尝试将数据发布或放置到API中,就会出现以下错误:
内部服务器错误:/ api / ordering /追溯(最近一次调用) 最后):文件 “ /home/neha/.local/lib/python3.5/site-packages/django/core/handlers/exception.py”, 第34行,在内部 response = get_response(request)文件“ /home/neha/.local/lib/python3.5/site-packages/django/core/handlers/base.py”, _get_response中的第126行 响应= self.process_exception_by_middleware(e,request)文件“ /home/neha/.local/lib/python3.5/site-packages/django/core/handlers/base.py”, _get_response中的第124行 响应= wraped_callback(request,* callback_args,** callback_kwargs)文件“ /home/neha/.local/lib/python3.5/site-packages/django/views/decorators/csrf.py”, 第54行,在wrapped_view中 返回view_func(* args,** kwargs)文件“ /home/neha/.local/lib/python3.5/site-packages/rest_framework/viewsets.py”, 第116行,视线范围 返回self.dispatch(request,* args,** kwargs)文件“ /home/neha/.local/lib/python3.5/site-packages/rest_framework/views.py”, 495行,正在调度中 响应= self.handle_exception(exc)文件“ /home/neha/.local/lib/python3.5/site-packages/rest_framework/views.py”, 第455行,在handle_exception中 self.raise_uncaught_exception(exc)文件“ /home/neha/.local/lib/python3.5/site-packages/rest_framework/views.py”, 492行,正在派遣中 响应=处理程序(请求,* args,** kwargs)文件“ /home/neha/.local/lib/python3.5/site-packages/rest_framework/mixins.py”, 第21行,在create中 self.perform_create(serializer)文件“ /home/neha/.local/lib/python3.5/site-packages/rest_framework/mixins.py”, 第26行,在perform_create中 serializer.save()文件“ /home/neha/.local/lib/python3.5/site-packages/rest_framework/serializers.py”, 第214行,保存 self.instance = self.create(validated_data)文件“ /home/neha/.local/lib/python3.5/site-packages/rest_framework/serializers.py”, 创建中的第929行 raise_errors_on_nested_writes('create',self,validated_data)文件 “ /home/neha/.local/lib/python3.5/site-packages/rest_framework/serializers.py”, 第823行,在raise_errors_on_nested_writes中 class_name = serializer。课程。名称
AssertionError:
.create()
方法不支持可写 默认情况下嵌套字段。为以下内容编写明确的.create()
方法 序列化器ordering.serializers.CustOrderSerializer
,或设置read_only=True
在嵌套的序列化程序字段上。
views.py
from ordering.models import CustOrder, Product, Price, City, Area
from rest_framework import viewsets, permissions
from .serializers import CustOrderSerializer, ProductSerializer,
PriceSerializer, CitySerializer, AreaSerializer
class CustOrderViewSet(viewsets.ModelViewSet):
queryset = CustOrder.objects.all()
permission_classes = [
permissions.AllowAny
]
serializer_class = CustOrderSerializer
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
permission_classes = [
permissions.AllowAny
]
serializer_class = ProductSerializer
class PriceViewSet(viewsets.ModelViewSet):
queryset = Price.objects.all()
permission_classes = [
permissions.AllowAny
]
serializer_class = PriceSerializer
class CityViewSet(viewsets.ModelViewSet):
queryset = City.objects.all()
permissions_classes = [
permissions.AllowAny
]
serializer_class = CitySerializer
class AreaViewSet(viewsets.ModelViewSet):
queryset = Area.objects.all()
permisions_classes = [
permissions.AllowAny
]
serializer_class = AreaSerializer
enter code here
serializer.py
from rest_framework import serializers
from ordering.models import CustOrder, Area, City, Product, Price
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
class PriceSerializer(serializers.ModelSerializer):
class Meta:
model = Price
fields = '__all__'
queryset=Product.objects.all())
# class AreaSerializer(serializers.ModelSerializer):
# class Meta:
# model = Area
# fields = '__all__'
class CitySerializer(serializers.ModelSerializer):
class Meta:
model = City
fields = '__all__'
class AreaSerializer(serializers.ModelSerializer):
class Meta:
model = Area
fields = '__all__'
class CustOrderSerializer(serializers.ModelSerializer):
price = serializers.SlugRelatedField(slug_field='price', queryset=Price.objects.all())
# product = serializers.SlugRelatedField(slug_field='product', queryset=Product.objects.all())
area = serializers.SlugRelatedField(slug_field='address', queryset=Area.objects.all())
city = serializers.SlugRelatedField(slug_field='city', queryset=City.objects.all())
product = ProductSerializer(many=True)
class Meta:
model = CustOrder
fields = '__all__'
def create(self, validated_data):
products = validated_data.pop('product')
product = Product.objects.create(**validated_data)
for products in products:
Product.objects.create(product=product, **products)
return product
# product = serializers.CharField(source="Product.product", read_only=True)
# price = serializers.CharField(source="Price.price", read_only=True)
# city = serializers.CharField(source="City.city", read_only=True)
# area = serializers.CharField(source="Area.area", read_only=True)
# price = serializers.SlugRelatedField(slug_field='price', queryset=Price.objects.all())
# product = serializers.SlugRelatedField(slug_field='product', queryset=Product.objects.all())
# area = serializers.SlugRelatedField(slug_field='address', queryset=Area.objects.all())
# city = serializers.SlugRelatedField(slug_field='city', queryset=City.objects.all())
# def to_representation(self, instance):
# response = super().to_representation(instance)
# response['child'] = ProductSerializer(instance.product).data
# return response
enter code here
model.py
from django.db import models
from phonenumber_field.modelfields import PhoneNumberField
from django.contrib.postgres.fields import ArrayField
from phone_field import PhoneField
from django.contrib.gis.db import models
from decimal import Decimal
from django.db.models import Sum
class City(models.Model):
city = models.CharField(max_length=200)
def __str__(self):
return self.city
class Meta:
verbose_name_plural = "Cities"
class Area(models.Model):
city = models.ForeignKey('City', on_delete=models.CASCADE)
address = models.CharField(max_length=200)
def __str__(self):
return self.address
class Product(models.Model):
product_id = models.AutoField(primary_key=True)
product = ArrayField(models.CharField(max_length=200, blank=True))
# price = models.DecimalField(max_digits=50, decimal_places = 5, default=0)
# def __str__(self):
# return str(self.product)+ ":$" + str(self.price)
# @property
# def price(self):
# return "$%s" % self.price
def __str__(self):
return str(self.product)
# def __str__(self):
# return "%s" % self.product_id
# def natural_key(self):
# return self.product
# class Meta:
# verbose_name_plural = "Products"
class Price(models.Model):
# product = models.ManyToManyField(Product, through='CustOrder', through_fields=('price', 'product'),)
# price_id = models.AutoField(primary_key=True)
price = models.DecimalField(max_digits=50, decimal_places = 5, default=0)
def __str__(self):
return "%s" % self.price
# return str(self.product)+ ":$" + str(self.price)
PRODUCT_CHOICES=(
('product_test_with_new_format','PRODUCT_TEST_WITH_NEW_FORMAT'),
('pulled chicken in pineapple relish','PULLED CHICKEN IN PINEAPPLE RELISH'),
('sundried sardines in mango relish', 'PULLED CHICKEN IN MANGO RELISH'),
('sundried sardines in mango relish','SUNDRIED SARDINES IN MANGO RELISH'),
)
GENDER_CHOICES = (
('male', 'MALE'),
('female', 'FEMALE'),
)
PAYMENT_CHOICES = (
('cod','COD'),
('card on delivery','CARD ON DELIVERY'),
('razor pay (netbanking)','RAZOR PAY (NET BANKING)'),
('razor pay (card)','RAZOR PAY (CARD)'),
('razor pay (wallet)','RAZOR PAY (WALLET)'),
('citrus','CITRUS'),
('paytm','PAYTM'),
)
CITY_CHOICES = (
('bangalore', 'BANGALORE'),
('hyderabad', 'HYDERABAD'),
('gurugram','GURUGRAM'),
('pune','PUNE'),
('chandigarh','CHANDIGARH'),
('mumbai','MUMBAI'),
)
# class ProductItem(models.Model):
# # product = models.ManyToManyField(Price, through='CustOrder')
# productitem = models.ManyToManyField(Product, through='CustOrder', through_fields=('productitem', 'product'),)
# def __str__(self):
# return str(self.productitem)
class CustOrder(models.Model):
Customer_id = models.AutoField(primary_key=True)
CustomerName = models.CharField(max_length=200)
email = models.EmailField(max_length=70,blank=True, null= True, unique= True)
gender = models.CharField(max_length=6, choices=GENDER_CHOICES)
phone = PhoneField(null=False, blank=True, unique=True)
landmark = models.PointField()
#landmark = models.TextField(max_length=400, help_text="Enter the landmark", default='Enter landmark')
houseno = models.IntegerField(default=0)
#product_name = models.CharField(max_length=200, choices=PRODUCT_CHOICES,default='Boneless chicken')
# product_id = models.ForeignKey(Product, on_delete=models.CASCADE,related_name='custorder_productid')
product = models.ManyToManyField(Product, blank=True,related_name='pricetag')
quantity = models.IntegerField(default=0)
# price_id = models.ForeignKey(Price)
price = models.ForeignKey(Price, on_delete=models.SET_NULL, null=True,related_name='pricetag')
#price = models.DecimalField(max_digits=50, decimal_places=5, default=48.9)
pay_method = models.CharField(max_length=200,choices=PAYMENT_CHOICES, default='RAZOR PAY')
city = models.ForeignKey(City, on_delete=models.SET_NULL, null=True)
area = models.ForeignKey(Area, on_delete=models.SET_NULL, null=True)
Price.objects.aggregate(Sum('price'))
def __str__(self):
return self.CustomerName
答案 0 :(得分:0)
我认为您的错误与以下事实有关:您将返回Product
对象而不是CustOrder
对象?
答案 1 :(得分:0)
就像错误消息所言,您必须在序列化器上编写owm .create()
方法,该方法负责在馈送的validated_data
上创建对象。
这样做,您可以明确地告诉Django如何处理嵌套字段