我看过很多关于如何反序列化和序列化具有多对多关系的表的嵌套关系的帖子,但是当在多对多关系中使用中间表时,我无法实现反序列化。
这是因为中间表需要两个外键,一个来自参与关系的两个表。
我有一个Order模型和一个Service模型,它们通过OrderItem中间表处于多对多关系中。
我需要像这样传递一个 JSON 请求:
{"service_time":"2015-11-14 10:00:51+0530",
"address":"xyz",
"items":[{"order": "1", "service_id":"4"},
{"order":"1", "service_id":"5"}]
}
“service_time”和“address”元素保存在Order表中。现在问题出现在“items”JSON 数组上。我将“service_id”(Service表的外键)传递给我,我也需要将“order”(Order 表的外键)传递给它,因为它是一个必填字段。问题是在发送请求时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
我收到一条错误消息,说'Service' 对象没有属性 '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:添加了其他相关的序列化程序。
我忘记提到的一件重要的事情是,数据保存在数据库中,但仍然引发异常。