Python 在Django rest框架中复制实例是否正确?
主要目的是创建现有文档的副本,内容相同但标题不同。为了实现这一点,我决定用自定义create方法实现另一个序列化程序。我必须修改视图类并动态确定调用哪种端点来选择合适的序列化程序。我的解决方案对我有效,但我怀疑这个解决方案是否正确 如果你对此有任何想法,请告诉我。 提前感谢您分享您的经验 我在开始时(修改前)有以下几点: model.pyPython 在Django rest框架中复制实例是否正确?,python,django,django-rest-framework,Python,Django,Django Rest Framework,主要目的是创建现有文档的副本,内容相同但标题不同。为了实现这一点,我决定用自定义create方法实现另一个序列化程序。我必须修改视图类并动态确定调用哪种端点来选择合适的序列化程序。我的解决方案对我有效,但我怀疑这个解决方案是否正确 如果你对此有任何想法,请告诉我。 提前感谢您分享您的经验 我在开始时(修改前)有以下几点: model.py ... class Document(models.Model): title = models.TextField('name', unique=T
...
class Document(models.Model):
title = models.TextField('name', unique=True)
content = models.TextField('content', default='')
...
class DocumentViewSet(viewsets.ModelViewSet):
queryset = Document.objects.all()
serializer_class = DocumentSerializer
...
class DocumentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Document
fields = ['id', 'url', 'title', 'content']
...
router = SimpleRouter()
router.register(r'documents', views.DocumentViewSet, basename='document')
...
# add new serializer
class DuplicateDocumentSerializer(serializers.HyperlinkedModelSerializer):
parent = serializers.HyperlinkedRelatedField(view_name='document-detail',
queryset=Document.objects.all(),
write_only=True)
content = serializers.ReadOnlyField()
def create(self, validated_data):
title = validated_data.get('title')
parent_doc = validated_data.get('parent')
content = parent_doc.content
return super().create({
'title': title,
'content': content,
})
class Meta:
model = Document
fields = ['id', 'url', 'title', 'content', 'parent']
...
class DocumentViewSet(viewsets.ModelViewSet):
queryset = Document.objects.all()
def get_serializer_class(self):
if self.action == 'copy':
return DuplicateDocumentSerializer
return DocumentSerializer
@transaction.atomic
@action(detail=False, methods=['post'])
def copy(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
view.py
...
class Document(models.Model):
title = models.TextField('name', unique=True)
content = models.TextField('content', default='')
...
class DocumentViewSet(viewsets.ModelViewSet):
queryset = Document.objects.all()
serializer_class = DocumentSerializer
...
class DocumentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Document
fields = ['id', 'url', 'title', 'content']
...
router = SimpleRouter()
router.register(r'documents', views.DocumentViewSet, basename='document')
...
# add new serializer
class DuplicateDocumentSerializer(serializers.HyperlinkedModelSerializer):
parent = serializers.HyperlinkedRelatedField(view_name='document-detail',
queryset=Document.objects.all(),
write_only=True)
content = serializers.ReadOnlyField()
def create(self, validated_data):
title = validated_data.get('title')
parent_doc = validated_data.get('parent')
content = parent_doc.content
return super().create({
'title': title,
'content': content,
})
class Meta:
model = Document
fields = ['id', 'url', 'title', 'content', 'parent']
...
class DocumentViewSet(viewsets.ModelViewSet):
queryset = Document.objects.all()
def get_serializer_class(self):
if self.action == 'copy':
return DuplicateDocumentSerializer
return DocumentSerializer
@transaction.atomic
@action(detail=False, methods=['post'])
def copy(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
序列化程序.py
...
class Document(models.Model):
title = models.TextField('name', unique=True)
content = models.TextField('content', default='')
...
class DocumentViewSet(viewsets.ModelViewSet):
queryset = Document.objects.all()
serializer_class = DocumentSerializer
...
class DocumentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Document
fields = ['id', 'url', 'title', 'content']
...
router = SimpleRouter()
router.register(r'documents', views.DocumentViewSet, basename='document')
...
# add new serializer
class DuplicateDocumentSerializer(serializers.HyperlinkedModelSerializer):
parent = serializers.HyperlinkedRelatedField(view_name='document-detail',
queryset=Document.objects.all(),
write_only=True)
content = serializers.ReadOnlyField()
def create(self, validated_data):
title = validated_data.get('title')
parent_doc = validated_data.get('parent')
content = parent_doc.content
return super().create({
'title': title,
'content': content,
})
class Meta:
model = Document
fields = ['id', 'url', 'title', 'content', 'parent']
...
class DocumentViewSet(viewsets.ModelViewSet):
queryset = Document.objects.all()
def get_serializer_class(self):
if self.action == 'copy':
return DuplicateDocumentSerializer
return DocumentSerializer
@transaction.atomic
@action(detail=False, methods=['post'])
def copy(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
url.py
...
class Document(models.Model):
title = models.TextField('name', unique=True)
content = models.TextField('content', default='')
...
class DocumentViewSet(viewsets.ModelViewSet):
queryset = Document.objects.all()
serializer_class = DocumentSerializer
...
class DocumentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Document
fields = ['id', 'url', 'title', 'content']
...
router = SimpleRouter()
router.register(r'documents', views.DocumentViewSet, basename='document')
...
# add new serializer
class DuplicateDocumentSerializer(serializers.HyperlinkedModelSerializer):
parent = serializers.HyperlinkedRelatedField(view_name='document-detail',
queryset=Document.objects.all(),
write_only=True)
content = serializers.ReadOnlyField()
def create(self, validated_data):
title = validated_data.get('title')
parent_doc = validated_data.get('parent')
content = parent_doc.content
return super().create({
'title': title,
'content': content,
})
class Meta:
model = Document
fields = ['id', 'url', 'title', 'content', 'parent']
...
class DocumentViewSet(viewsets.ModelViewSet):
queryset = Document.objects.all()
def get_serializer_class(self):
if self.action == 'copy':
return DuplicateDocumentSerializer
return DocumentSerializer
@transaction.atomic
@action(detail=False, methods=['post'])
def copy(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
我当前的解决方案是修改如下文件:
序列化程序.py
...
class Document(models.Model):
title = models.TextField('name', unique=True)
content = models.TextField('content', default='')
...
class DocumentViewSet(viewsets.ModelViewSet):
queryset = Document.objects.all()
serializer_class = DocumentSerializer
...
class DocumentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Document
fields = ['id', 'url', 'title', 'content']
...
router = SimpleRouter()
router.register(r'documents', views.DocumentViewSet, basename='document')
...
# add new serializer
class DuplicateDocumentSerializer(serializers.HyperlinkedModelSerializer):
parent = serializers.HyperlinkedRelatedField(view_name='document-detail',
queryset=Document.objects.all(),
write_only=True)
content = serializers.ReadOnlyField()
def create(self, validated_data):
title = validated_data.get('title')
parent_doc = validated_data.get('parent')
content = parent_doc.content
return super().create({
'title': title,
'content': content,
})
class Meta:
model = Document
fields = ['id', 'url', 'title', 'content', 'parent']
...
class DocumentViewSet(viewsets.ModelViewSet):
queryset = Document.objects.all()
def get_serializer_class(self):
if self.action == 'copy':
return DuplicateDocumentSerializer
return DocumentSerializer
@transaction.atomic
@action(detail=False, methods=['post'])
def copy(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
view.py
...
class Document(models.Model):
title = models.TextField('name', unique=True)
content = models.TextField('content', default='')
...
class DocumentViewSet(viewsets.ModelViewSet):
queryset = Document.objects.all()
serializer_class = DocumentSerializer
...
class DocumentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Document
fields = ['id', 'url', 'title', 'content']
...
router = SimpleRouter()
router.register(r'documents', views.DocumentViewSet, basename='document')
...
# add new serializer
class DuplicateDocumentSerializer(serializers.HyperlinkedModelSerializer):
parent = serializers.HyperlinkedRelatedField(view_name='document-detail',
queryset=Document.objects.all(),
write_only=True)
content = serializers.ReadOnlyField()
def create(self, validated_data):
title = validated_data.get('title')
parent_doc = validated_data.get('parent')
content = parent_doc.content
return super().create({
'title': title,
'content': content,
})
class Meta:
model = Document
fields = ['id', 'url', 'title', 'content', 'parent']
...
class DocumentViewSet(viewsets.ModelViewSet):
queryset = Document.objects.all()
def get_serializer_class(self):
if self.action == 'copy':
return DuplicateDocumentSerializer
return DocumentSerializer
@transaction.atomic
@action(detail=False, methods=['post'])
def copy(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
在本例中,我使用这些端点
创建新文档的步骤
职位:
复制现有文档的步骤
职位:
在我看来,像这样使用URL会更好
职位:
不幸的是,我还没有找到一个优雅的解决方案。
也许这两种情况我都错了