python - Django rest 框架 - 可写(创建,更新)双嵌套序列化程序
问题描述
我正在尝试使用 DJANGO REST FRAMEWORK 创建一个嵌套序列化程序。
但我不知道如何在 serializer.py 中使用创建更新方法。我已经创建了模型和一些可用的序列化程序。
模型.py
class JournalEntry(models.Model):
CHOICES = (
('SALES', 'Sales'),
('PURCHASE', 'Purchase'),
('DEBITNOTE', 'DebitNote'),
('CREDITNOTE', 'CreditNote'),
('COSTOMER_RECIEPT', 'CustomerReceipt'),
('SUPPLIER_PAYMENT', 'SupplierPayment'),
('EXPENSE', 'Expense'),
('JOURNAL', 'Journal'),
)
date = models.DateField()
transaction_type = models.CharField(max_length=15, choices=CHOICES, default='SALES',null=True, blank=True)
description = models.CharField(max_length=15,null=True, blank=True)
@property
def child(self):
return self.journalitem_set.all()
class JournalItem(models.Model):
journal_entry = models.ForeignKey('core.JournalEntry', on_delete=models.CASCADE)
account = models.CharField(max_length=15, choices=CHOICES, default='SALES',null=True, blank=True)
partner = models.ForeignKey(Customer, on_delete=models.CASCADE, null=True, blank=True)
debit_amount = models.DecimalField(max_digits=15,decimal_places=2,null=True, blank=True)
credit_amount = models.DecimalField(max_digits=15,decimal_places=2,null=True, blank=True)
class CustomerReceipt(models.Model):
reciept_no = models.IntegerField()
journal_entry = models.ForeignKey(JournalEntry, on_delete=models.CASCADE, null=True, blank=True)
serializer.py,一些必需的序列化程序已经完成。
class JournalItemSerializer(serializers.ModelSerializer):
id = serializers.IntegerField(required=False)
class Meta:
model = JournalItem
fields = [
'id','journal_entry',
'account','partner',
'debit_amount','credit_amount'
]
read_only_fields = ('journal_entry',)
class JournalEntrySerializer(serializers.ModelSerializer):
child = JournalItemSerializer(many=True)
class Meta:
model = JournalEntry
fields = ('id','date','transaction_type','description','child')
def create(self, validated_data):
albums_data = validated_data.pop('child')
musician = JournalEntry.objects.create(**validated_data)
for album_data in albums_data:
JournalItem.objects.create(journal_entry=musician, **album_data)
return musician
def update(self, instance, validated_data):
child = validated_data.pop('child')
# albums = (instance.child).all()
# albums = list(albums)
instance.date = validated_data.get('date', instance.date)
instance.transaction_type = validated_data.get('transaction_type', instance.transaction_type)
instance.description = validated_data.get('description', instance.description)
instance.save()
keep_choices = []
for choice in child:
if "id" in choice.keys():
if JournalItem.objects.filter(id=choice["id"]).exists():
c = JournalItem.objects.get(id=choice["id"])
c.account = choice.get('account', c.account)
c.partner = choice.get('partner', c.partner)
c.debit_amount = choice.get('debit_amount', c.debit_amount)
c.credit_amount = choice.get('credit_amount', c.credit_amount)
c.save()
keep_choices.append(c.id)
else:
continue
else:
c = JournalItem.objects.create(**choice, journal_entry=instance)
keep_choices.append(c.id)
for choice in instance.child:
if choice.id not in keep_choices:
choice.delete()
return instance
我需要在CustomerReceiptSerializer中添加创建和更新方法。我需要在对应的 api 上进行所有操作(DELETE、PUT、PATCH $ POST)。
class CustomerReceiptSerializer(serializers.ModelSerializer):
journal_entry = JournalEntrySerializer()
class Meta:
model = CustomerReceipt
# fields = ('reciept_no', 'journal_entry')
fields = "__all__"
def create:
......
def update:
......
class CustomerReceiptViewSet(viewsets.ModelViewSet):
serializer_class = serializers.CustomerReceiptSerializer
queryset = models.CustomerReceipt.objects.all()
输出像,
{
"id": 1,
"journal_entry": {
"id": 1,
"date": "2019-05-09",
"transaction_type": "SALES",
"description": "description",
"child": [
{
"id": 1,
"journal_entry": 1,
"account": "Sales",
"partner": null,
"debit_amount": "400.00",
"credit_amount": "400.00"
},
{
"id": 1,
"journal_entry": 1,
"account": "Purchase",
"partner": null,
"debit_amount": "800.00",
"credit_amount": "400.00"
}
]
},
"reciept_no": 1
}
json data for post into api is like,
{
"reciept_no": 1
"journal_entry": {
"date": "2019-05-09",
"transaction_type": "SALES",
"description": "description",
"child": [
{
"account": "Sales",
"partner": null,
"debit_amount": "400.00",
"credit_amount": "400.00"
},
{
"account": "Purchase",
"partner": null,
"debit_amount": "800.00",
"credit_amount": "400.00"
}
]
}
}
iam using ,
Django - 2.1.3,
djangorestframework - 3.9.0
解决方案
在 JournalEntrySerializer 中,创建与 CustomerReceipt 模型的关系。
child = JournalItemSerializer(many=True)
costumer = CustomerReceipt()
注意:CustomerReceipt() 也可能收到 many=True。
然后,在 JournalEntrySerializer 的 create() 和 update() 中,可以记录 CustomerReceipt。
推荐阅读
- python - selenium:如何在 mac 上加载本地 html 文件?
- c# - 如果对象不存在,如何获取对象并创建新对象?
- sql - 如何在 Teradata 选择语句中替换多个字符串
- python - 如何在不使用 Scikit-Learn 的情况下对归一化数据执行回归后检索原始系数?
- mysql - 如果 transaction.Rollback/Commit 在关闭连接之前从未调用过会发生什么?
- javascript - 可以访问event.target,它有value属性,但是event.target.value总是返回undefined?
- ruby - 如何将嵌套方法中声明的局部变量设置在父方法的范围内?
- php - 如何通过产品变体对可变产品进行 WC meta_query?
- mysql - 选择由两个不同值相互共享的项目列表
- r - ggplot geom_boxplot 渲染非常缓慢