Python 在DRF中处理相关模型并为其获取正确的招摇过市文档
所以我有点麻烦,因为我想做的事 基本上,我有这些模型:Python 在DRF中处理相关模型并为其获取正确的招摇过市文档,python,django,django-rest-framework,swagger,drf-yasg,Python,Django,Django Rest Framework,Swagger,Drf Yasg,所以我有点麻烦,因为我想做的事 基本上,我有这些模型: class Package(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) title = models.CharField(max_length=255, null=False, blank=False) contact = models.BooleanField(default=False) downloade
class Package(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=255, null=False, blank=False)
contact = models.BooleanField(default=False)
downloaded = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True)
class Item(models.Model):
[…. all the atributes of the item model….]
class PackageItems(models.Model):
package = models.ForeignKey(Package, on_delete=models.CASCADE)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
现在我正在尝试创建一个端点,允许我的用户添加“包”,并将项目模型中预先存在的项目添加到新创建的包中。一个包裹当然可以有很多物品
因此,我编写了一个包序列化程序,然后添加了一个SerializerMethodField,允许对给定包包含的任何项执行get操作。该方法调用不同的序列化程序。
以下是两个序列化程序的代码:
class PackageItemsSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = PackageItems
fields = ('package', 'item')
class PackagesSerializer(serializers.ModelSerializer):
"""
Creation only requires a title
"""
package_items = serializers.SerializerMethodField(read_only=True)
@swagger_serializer_method(serializer_or_field=packageItemsSerializer)
def get_package_items(self, obj):
packageItems = PackageItems.objects.all().filter(package=obj.id)
return PackageItemsSerializer(packageItems, many=True, context={'request': self.context['request']}).data
def create(self, validated_data):
package = super(packagesSerializer, self).create(validated_data)
return package
class Meta:
model = packages
fields = ('id', 'user', 'title', 'contact', 'downloaded', 'created', 'package_items')
read_only_fields = [ 'user', 'contact', 'downloaded', 'package_items’]
关于我的观点,我决定这样做:
class PackagesViewSet(viewsets.ModelViewSet):
queryset = Packages.objects.all()
serializer_class = PackagesSerializer
permission_classes = [permissions.IsAuthenticated]
def get_queryset(self):
if getattr(self, 'swagger_fake_view', False):
return Packages.objects.none()
return Packages.objects.filter(user=self.request.user).order_by('id')
def perform_create(self, serializer):
# sending default values for user, contact and downloaded
serializer.save(user=self.request.user, contact=False, downloaded=False)
def partial_update(self, request, *args, **kwargs):
response_with_updated_instance = super(PackagesViewSet, self).partial_update(request, *args, **kwargs)
return response_with_updated_instance
@action(methods=['post', 'delete'], detail=True, serializer_class=PackageItemsSerializer)
def item(self, request, pk=None):
package = self.get_object()
serializer = self.get_serializer_class()(data=request.data)
if serializer.is_valid():
serializer.save(package=package)
return Response(serializer.data)
else:
return Response(status=status.HTTP_400_BAD_REQUEST)
if request.method == 'delete':
serializer.delete(package=package)
这就是它的工作原理:
我有以下路线:
[获取/发布]用于/api/packages/
/api/packages/{id}
[发布/删除]用于/api/packages/{id}/item
我找到了正确的路线,但首先,斯威格给了我错误的post模型:
{
"title": "string",
"package_items": {
"items": 0
}
}
不确定为什么在我发布到/api/packages
时希望输入此只读字段(这也是serializermethodfield)
类似地,这些字段显示在/api/packages/{id}
下
对于嵌套的“item”路由,POST
可以很好地工作,但是DELETE
不能。POST路由允许我输入项目ID,并将其添加到/api/packages/{ID}/item
路由下的给定包ID中。
但是delete不允许我输入要删除的项目ID
因此,我认为我对嵌套项的delete方法是完全错误的
我是DRF/django的新手,正在尝试验证我是否朝着正确的方向前进
如何让drf yasg为HTTP动词(例如POST)找到正确的模型?
删除嵌套项的正确方法是什么
我处理这个问题对吗?还有其他更有效的方法吗
如果有人能帮我回答这些问题,我将不胜感激:)
提前谢谢各位 不要在
序列化程序中嵌套序列化程序
。SerializerMethodField
直接嵌套它,就像:
package_item = PackageItemsSerializer(source="package_set", many=True, read_only=True)
试试这个继续玩这个,使用不同的序列化程序执行不同的操作。对于“我的软件包”部分的作品,招摇过市的文档看起来很好,模型很好,所有内容的表示也很好