具有中间表的多对多关系的django嵌套序列化
我看过很多关于如何对具有多对多关系的表的嵌套关系进行反序列化和序列化的文章,但是当在多对多关系中使用中间表时,我无法实现反序列化 这是因为中间表需要两个外键,每个外键来自参与关系的两个表 我有一个订单模型和一个服务模型,它们通过一个订单项中间表处于多对多关系中 我需要像这样传递一个JSON请求:具有中间表的多对多关系的django嵌套序列化,django,serialization,django-rest-framework,django-serializer,Django,Serialization,Django Rest Framework,Django Serializer,我看过很多关于如何对具有多对多关系的表的嵌套关系进行反序列化和序列化的文章,但是当在多对多关系中使用中间表时,我无法实现反序列化 这是因为中间表需要两个外键,每个外键来自参与关系的两个表 我有一个订单模型和一个服务模型,它们通过一个订单项中间表处于多对多关系中 我需要像这样传递一个JSON请求: {"service_time":"2015-11-14 10:00:51+0530", "address":"xyz", "items":[{"order": "1", "service_id
{"service_time":"2015-11-14 10:00:51+0530",
"address":"xyz",
"items":[{"order": "1", "service_id":"4"},
{"order":"1", "service_id":"5"}]
}
“服务时间”和“地址”元素保存在订单中。现在,“items”JSON数组出现了问题。我传递“service_id”(外键到service表)并且我也需要传递“order”(外键到order表),因为它是必填字段。问题在于发送请求时,订单表的主键未知(因为订单也是作为同一请求的一部分创建的)。在这种情况下,如何实现反序列化
我试过这样的方法,但没有成功
class OrderSerializer(serializers.ModelSerializer):
items = ItemSerializer(many=True)
class Meta:
model = Order
def create(self, validated_data):
items_data = validated_data.pop('items')
orders = Order.objects.create(**validated_data)
for item in items_data:
#order = item['order']
service = item['service']
//Passing the Order object just created as the foreign key of OrderItem
orderItem = OrderItem.objects.create(order=orders, service=service)
orderItem.save()
return orders
class ServiceSerializer(serializers.ModelSerializer):
group = serializers.CharField(source="group.group_name")
category = serializers.IntegerField(source="group.category_id")
class Meta:
model = Service
fields = ['id', 'service_name', 'price', 'special_price', 'service_time', 'group', 'category']
class ItemSerializer(serializers.ModelSerializer):
service_detail = ServiceSerializer(source="service", read_only=True)
class Meta:
model = OrderItem
我得到一个错误,说“服务”对象没有属性“顺序”
我知道服务模型没有“order”属性,但我正在创建一个OrderItem对象,而不是服务对象
任何建议都会有帮助
编辑:添加使用的模型
class Order(models.Model):
STATUSES = [('PENDING', 'Pending'), ('PROCESSING', 'Processing'), ('COMPLETE', 'Complete'), ('CANCELED', 'Canceled')]
PAYMENT_STATUSES = [('PENDING', 'Pending'), ('PAID', 'Paid'),]
CANCEL_REASON = [('NO_SERVICE', 'No Service In Area'), ('NO_STYLIST', 'Stylist Not Available'), ('STYLIST_REFUSED', 'Stylist Refused After Accepting',),
('CUSTOMER_UNREACHABLE', 'Customer Not Reachable'), ('CUSTOMER_CANCELED', 'Customer Canceled at Fisrt Call'), ('CUSTOMER_REFUSED', 'Customer Refused at Last Moment'),
('DUPLICATE_ORDER', 'Duplicate Order'), ('MALE_CLIENT', 'Male Client'), ('CALLCENTER_DELAY', 'Delay/Error at Frontdesk')]
serial = models.CharField(max_length=10, null=True, blank=True,)
customer = models.ForeignKey(Customer, verbose_name="customer", related_name="ordersbycustomer")
stylist = models.ForeignKey(Stylist, null=True, blank=True, verbose_name="stylist", related_name="ordersbystylist")
# TODO, Use timezone.now
service_time = models.DateTimeField(default=timezone.now, blank=True)
started_moving = models.DateTimeField(null=True, blank=True)
service_start_at = models.DateTimeField(null=True, blank=True)
service_end_at = models.DateTimeField(null=True, blank=True)
reached_safely = models.DateTimeField(null=True, blank=True)
sub_total = models.FloatField(default=0)
discounts = models.FloatField(default=0)
grand_total = models.FloatField(default=0)
total_time = models.IntegerField(default=0)
status = models.CharField(max_length=32, choices=STATUSES, default='PENDING')
payment_status = models.CharField(max_length=32, choices=PAYMENT_STATUSES, default='PENDING')
items = models.ManyToManyField(Service, through='OrderItem')
address = models.ForeignKey(Address, null=True, blank=True, related_name='+', on_delete=models.SET_NULL)
amount_received = models.FloatField(default=0)
send_sms = models.BooleanField(default=True)
thru_app = models.BooleanField(default=True)
referral_discount = models.FloatField(default=0)
cancellation_reason = models.CharField(max_length=64, choices=CANCEL_REASON, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __unicode__(self):
return self.serial
def _get_service_list(self):
return ','.join(str(p.description) for p in self.items.all())
service_list = property(_get_service_list)
class Service(models.Model):
group = models.ForeignKey(Group, related_name="services")
service_name = models.CharField(max_length=128)
price = models.FloatField(default=0)
special_price = models.FloatField(default=0)
service_time = models.IntegerField()
description = models.CharField(max_length=123)
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __unicode__(self):
return '{} ({})'.format(self.service_name, self.group)
class OrderItem(models.Model):
order = models.ForeignKey(Order)
service = models.ForeignKey(Service)
price = models.FloatField(default=0)
special_price = models.FloatField(default=0)
qty = models.IntegerField(default=1)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __unicode__(self):
return self.service.service_name
Edit2:添加了其他相关序列化程序。
我忘了提到的一件重要事情是,数据保存在数据库中,但仍会引发异常。您的FK字段是否有相关的名称?这是序列化程序中应该具有的文件名。如果我们能看到模型也会很有帮助。为什么相关的名称在这里很重要?再多解释一下会有帮助的。我想我第一次没理解你的问题。很难理解您的问题,因为您的问题中没有描述您的模型。我认为你应该做一些类似service=service.objects.create(**你的参数)是的,如果我不对m2m关系使用中间表,你所说的是正确的。既然有了一个名为“OrderItem”的中间表,为什么要调用Service.objects.create?我应该在中间OrderItem表中创建条目,对吗?根据此链接,如果显式指定了中间表,则不能创建“服务”对象。您的FK字段是否有相关的_名称?这是序列化程序中应该具有的文件名。如果我们能看到模型也会很有帮助。为什么相关的名称在这里很重要?再多解释一下会有帮助的。我想我第一次没理解你的问题。很难理解您的问题,因为您的问题中没有描述您的模型。我认为你应该做一些类似service=service.objects.create(**你的参数)是的,如果我不对m2m关系使用中间表,你所说的是正确的。既然有了一个名为“OrderItem”的中间表,为什么要调用Service.objects.create?我应该在中间OrderItem表中创建条目,对吗?根据此链接,如果显式指定了中间表,则不能创建“服务”对象。