更新 Django Rest Framework 中的多对多关系

Orders在我的 django 应用程序中,我在和之间建立了多对多关系Packages。一个订单可以有多个包裹。我想了解更新和创建方法


模型.py


class Package(models.Model):


    prod_name = models.CharField(max_length=255, default=0)

    quantity = models.IntegerField(default=0)

    unit_price = models.IntegerField(default=0)


class Orders(models.Model):


    order_id = models.CharField(max_length=255, default=0)

    package = models.ManyToManyField(Package)

    is_cod = models.BooleanField(default=False)

序列化程序.py


class PackageSerializer(serializers.ModelSerializer):

    class Meta:

        model = Package

        fields = "__all__"


class OrderSerializer(serializers.ModelSerializer):

    package = PackageSerializer(many=True)


    class Meta:

        model = Orders

        fields = "__all__"

视图.py


class OrdersCreateAPIView(generics.CreateAPIView):

    permission_classes = (permissions.IsAuthenticated,)

    serializer_class = OrderSerializer


    def post(self, request):


        serializer = OrderSerializer(data=request.data)

        if serializer.is_valid():

            serializer.save()

            return Response(serializer.data, status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

这足以处理相关数据吗?我正在尝试了解ManytoManyDjango 和 DRF 中的关系,所以请解释我是否需要更改模型或视图


更新:


我已经更新了我的序列化程序和视图,以便创建manytomany像这样的相关对象:


class OrderSerializer(serializers.ModelSerializer):

    package = PackageSerializer(many=True)


    class Meta:

        model = Orders

        fields = "__all__"


    def create(self, validated_data):

        package_data = validated_data.pop('package')

        pkgs = []

        order = Orders.objects.create(**validated_data)

        for i in package_data:

            try:

                p = Package.objects.create(**i)

                pkgs.append(p)

            except:

                pass

        order.package.set(pkgs)

        return order


但是我仍然不清楚覆盖update. RetrieveUpdateDestroyAPIView另外,上述方法是存储M2M相关对象的正确方法吗?


请帮助更新序列化程序的部分,我知道我必须在序列化程序中传递查询


交互式爱情
浏览 118回答 1
1回答

慕姐8265434

工作代码库#serializers.pyclass PackageSerializer(serializers.ModelSerializer):&nbsp; &nbsp; id = serializers.IntegerField()&nbsp; &nbsp; class Meta:&nbsp; &nbsp; &nbsp; &nbsp; model = Package&nbsp; &nbsp; &nbsp; &nbsp; fields = "__all__"class OrderSerializer(serializers.ModelSerializer):&nbsp; &nbsp; package = PackageSerializer(many=True)&nbsp; &nbsp; def get_or_create_packages(self, packages):&nbsp; &nbsp; &nbsp; &nbsp; package_ids = []&nbsp; &nbsp; &nbsp; &nbsp; for package in packages:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; package_instance, created = Package.objects.get_or_create(pk=package.get('id'), defaults=package)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; package_ids.append(package_instance.pk)&nbsp; &nbsp; &nbsp; &nbsp; return package_ids&nbsp; &nbsp; def create_or_update_packages(self, packages):&nbsp; &nbsp; &nbsp; &nbsp; package_ids = []&nbsp; &nbsp; &nbsp; &nbsp; for package in packages:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; package_instance, created = Package.objects.update_or_create(pk=package.get('id'), defaults=package)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; package_ids.append(package_instance.pk)&nbsp; &nbsp; &nbsp; &nbsp; return package_ids&nbsp; &nbsp; def create(self, validated_data):&nbsp; &nbsp; &nbsp; &nbsp; package = validated_data.pop('package', [])&nbsp; &nbsp; &nbsp; &nbsp; order = Orders.objects.create(**validated_data)&nbsp; &nbsp; &nbsp; &nbsp; order.package.set(self.get_or_create_packages(package))&nbsp; &nbsp; &nbsp; &nbsp; return order&nbsp; &nbsp; def update(self, instance, validated_data):&nbsp; &nbsp; &nbsp; &nbsp; package = validated_data.pop('package', [])&nbsp; &nbsp; &nbsp; &nbsp; instance.package.set(self.create_or_update_packages(package))&nbsp; &nbsp; &nbsp; &nbsp; fields = ['order_id', 'is_cod']&nbsp; &nbsp; &nbsp; &nbsp; for field in fields:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setattr(instance, field, validated_data[field])&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; except KeyError:&nbsp; # validated_data may not contain all fields during HTTP PATCH&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pass&nbsp; &nbsp; &nbsp; &nbsp; instance.save()&nbsp; &nbsp; &nbsp; &nbsp; return instance&nbsp; &nbsp; class Meta:&nbsp; &nbsp; &nbsp; &nbsp; model = Orders&nbsp; &nbsp; &nbsp; &nbsp; fields = "__all__"#views.pyclass OrderViewSet(viewsets.ModelViewSet):&nbsp; &nbsp; serializer_class = OrderSerializer&nbsp; &nbsp; queryset = Orders.objects.all()DefaultRouter在as的帮助下注册此视图,from rest_framework.routers import DefaultRouterrouter = DefaultRouter()router.register(r'order', OrderViewSet, basename='order')urlpatterns = [&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ] + router.urls因此,您将获得该表中描述的基本 CRUD 端点(参见DefaultRouter参考文献)。让您的订单列表端点成为/foo-bar/order/HTTP POST 来/foo-bar/order/创建一个新实例HTTP PUT 或 HTTP PATCH/foo-bar/order/<ORDER_PK>/以更新内容笔记在这种情况下,id如果您希望将现有的包关系映射到Order更新-1您可以像这样连接视图urlpatterns = [&nbsp; &nbsp; path('foo/order/', OrderViewSet.as_view({'post': 'create'})),&nbsp; # create new Order instance&nbsp; &nbsp; path('foo/order/<int:pk>/', OrderViewSet.as_view({'patch': 'partial_update'})),&nbsp; # update Order instance]注意:这仅支持HTTP POST和HTTP PATCH
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python