[英]Django REST framework - 3 models related to one another, DELETE request fails
[英]Django REST Framework: save/update/delete object with related in one transaction. How to?
我想問你,如何使用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
JSON輸入:
{
"title": "..",
"description": "..",
"notifications": [{"first_name": "", "email": ""}, ...]
"images": [{"title": "", "url": ""}, ...]
"attributes": [{"name": "", "value": ""}, ...]
}
因此,我認為“添加”這樣的結構非常簡單,但是“更新”(或“修補”)和“刪除”(例如圖像之一)又如何呢? 整個請求應在事務中完成,例如:如果我們對出版物的標題和圖像的url進行了一些編輯,並且url的格式錯誤,則我們既不應保存發布對象,也不應保存圖像對象。
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.