python - 覆盖 Django restframework 嵌套序列化程序的创建方法
问题描述
我正在尝试在 django-rest-framework 中使用嵌套的可写序列化程序。当我发送带有以下数据的 POST 请求时:
{
"acc_name": "Salary Card",
"acc_type_id": {
"id": 2,
"acc_type_name": "Debit Card"
},
"credit_amt": null,
"bill_dt": null,
"due_dt": null,
"balance": "0.00",
"comments": null
}
我收到一个错误:
Cannot assign "OrderedDict([('acc_type_name', 'Debit Card')])": "Accounts.acc_type_id" must be a "AccountTypes" instance.
我实际上为 AccountTypes 传递了 id,但为什么 restframework 会自动删除它?我该如何解决这个问题?如何使用现有帐户类型创建新帐户?
意见:
class AccountTypesViewSet(ListAPIView):
name = __name__
pagination_class = None
queryset = AccountTypes.objects.filter(active='Y')
serializer_class = AccountTypesSerializer
class AccountsViewSet(viewsets.ModelViewSet):
pagination_class = None
queryset = Accounts.objects.all()
serializer_class = AccountsSerializer
楷模:
class AccountTypes(models.Model):
id = models.AutoField(primary_key=True, editable=False)
acc_type_name = models.CharField(max_length=50)
active = models.CharField(max_length=1, default='Y')
class Meta:
db_table = f'"{schema}"."taccount_types"'
managed = False
class Accounts(models.Model):
id = models.AutoField(primary_key=True, editable=False)
acc_name = models.CharField(max_length=1024)
acc_type_id = models.ForeignKey(
to=AccountTypes,
db_column='acc_type_id',
related_name='accounts',
on_delete=models.DO_NOTHING
)
credit_amt = models.DecimalField(max_digits=11, decimal_places=2, null=True)
bill_dt = models.DateField(null=True)
due_dt = models.DateField(null=True)
balance = models.DecimalField(max_digits=11, decimal_places=2, default=0)
comments = models.CharField(max_length=1024, null=True)
class Meta:
db_table = f'"{schema}"."taccounts"'
managed = False
序列化器:
class AccountTypesSerializer(serializers.ModelSerializer):
class Meta:
model = AccountTypes
fields = ('id', 'acc_type_name')
class AccountsSerializer(serializers.ModelSerializer):
# acc_type = serializers.SlugRelatedField(slug_field='acc_type_name', source='acc_type_id', read_only=True)
acc_type_id = AccountTypesSerializer()
class Meta:
model = Accounts
fields = ('id', 'acc_name', 'acc_type_id', 'credit_amt',
'bill_dt', 'due_dt', 'balance', 'comments')
def create(self, validated_data):
accounts_instance = Accounts.objects.create(**validated_data)
return accounts_instance
解决方案
你不需要设置id
字段,因为 Django 会自己做,所以删除这些行:
id = models.AutoField(primary_key=True, editable=False)
接下来,您需要发送一个id
模型AccountTypes
来创建新帐户,然后给 Django 一个 dict fields = ('id', 'acc_type_name')
。它不知道该怎么办。所以只需发送id
号码。你也不需要AccountTypesSerializer
那条线acc_type_id = AccountTypesSerializer()
。
接下来,您应该在视图中创建帐户,而不是在序列化程序中,并且您必须在创建后保存它。
推荐阅读
- php - MYSQL 在屏幕上分段打印日期
- python - 根据条件从数组中选择元素
- java - 向字符串值添加双引号时遇到问题。第二个引号显示远离值
- spring-mvc - Bootstrap not loading on computer
- node.js - 使用 Koa 和 Typescript 将文件上传到 S3 兼容存储
- javascript - error TS2532: Object is possibly 'undefined'
- scala - How to define traits that statically guarantee that an object and one of its fields both share a same label
- java - How to @Autowired (inject) from xml. Could not autowire. No beans of 'DAO' type found
- javascript - 为什么 JavaScript 需要 ECMAScript 标准?
- javascript - 使用节点运行 twitter 时出现状态错误 401。可能的授权错误