Use*_*ser 0 python django django-rest-framework
我想问你,如何使用 DRF 处理添加/编辑/删除具有许多内联对象(如在 Django Admin + FormSet 中)的对象。例如:
Publication:
- title
- description
+ Notofications (1 and more)
- first_name
- email
+ Images (1 and more)
- title
- url
+ Attributes (1 and more)
- name
- value
Run Code Online (Sandbox Code Playgroud)
JSON 输入:
{
"title": "..",
"description": "..",
"notifications": [{"first_name": "", "email": ""}, ...]
"images": [{"title": "", "url": ""}, ...]
"attributes": [{"name": "", "value": ""}, ...]
}
Run Code Online (Sandbox Code Playgroud)
所以我认为“添加”这样的结构很简单,但是“更新”(或“修补”)和“删除”(例如其中一张图像)怎么样?整个请求应该在事务中完成,例如:如果我们对出版物的标题和图片的网址进行了一些编辑,并且网址格式错误,我们不应该保存出版物对象和图片对象。
REST API 中是否有好的模式?
谢谢你。
我建议使用嵌套序列化程序来完成它:
class NestedNotificationSerializer(serializers.ModelSerializer):
class Meta:
model = models.Notification
fields = ('id', 'first_name', 'email')
def to_internal_value(self, data):
""" Return exist notification as internal value if id is provided """
if 'id' in data:
try:
return models.Notification.objects.get(id=data['id'])
except models.Notification.DoesNotExists:
raise serializers.ValidationError('Notification with id %s does not exist' % data['id'])
else:
internal_data = super(NestedNotificationSerializer, self).to_internal_value(data)
return models.Notification(**internal_data)
class PublicationSerializer(serializers.ModelSerializer):
notifications = NestedNotificationSerializer(many=True)
...
def create(self, validated_data):
notifications = validated_data.pop('notifications', [])
# create publication and its notifications in one transaction
with transaction.atomic():
publication = super(PublicationSerializer, self).create(validated_data)
for notification in notifications:
publication.notifications.add(notification)
return publication
def update(self, instance, validated_data):
notifications = validated_data.pop('notifications', [])
new_notifications = [notification for notification in notifications if notification.id is None]
existed_notifications = set([notification for notification in notifications if notification.id is not None])
# update publication and its notifications in one transaction:
with transaction.atomic():
publication = super(PublicationSerializer, self).update(instance, validated_data)
old_notifications = set(publication.notifications.all())
removed_notifications = old_notifications - existed_notifications
for notification in removed_notifications:
notification.delete()
for notification in new_notifications:
publication.notifications.add(notification)
return publication
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1280 次 |
| 最近记录: |