为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

交互式爱情 2022-11-01 15:46:49
Orders在我的 django 应用程序中,我在和之间建立了多对多关系Packages。一个订单可以有多个包裹。我想了解更新和创建方法模型.pyclass 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)序列化程序.pyclass PackageSerializer(serializers.ModelSerializer):    class Meta:        model = Package        fields = "__all__"class OrderSerializer(serializers.ModelSerializer):    package = PackageSerializer(many=True)    class Meta:        model = Orders        fields = "__all__"视图.pyclass 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相关对象的正确方法吗?请帮助更新序列化程序的部分,我知道我必须在序列化程序中传递查询
查看完整描述

1 回答

?
慕姐8265434

TA贡献1813条经验 获得超2个赞

工作代码库

#serializers.py

class PackageSerializer(serializers.ModelSerializer):

    id = serializers.IntegerField()


    class Meta:

        model = Package

        fields = "__all__"



class OrderSerializer(serializers.ModelSerializer):

    package = PackageSerializer(many=True)


    def get_or_create_packages(self, packages):

        package_ids = []

        for package in packages:

            package_instance, created = Package.objects.get_or_create(pk=package.get('id'), defaults=package)

            package_ids.append(package_instance.pk)

        return package_ids


    def create_or_update_packages(self, packages):

        package_ids = []

        for package in packages:

            package_instance, created = Package.objects.update_or_create(pk=package.get('id'), defaults=package)

            package_ids.append(package_instance.pk)

        return package_ids


    def create(self, validated_data):

        package = validated_data.pop('package', [])

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

        order.package.set(self.get_or_create_packages(package))

        return order


    def update(self, instance, validated_data):

        package = validated_data.pop('package', [])

        instance.package.set(self.create_or_update_packages(package))

        fields = ['order_id', 'is_cod']

        for field in fields:

            try:

                setattr(instance, field, validated_data[field])

            except KeyError:  # validated_data may not contain all fields during HTTP PATCH

                pass

        instance.save()

        return instance


    class Meta:

        model = Orders

        fields = "__all__"


#views.py

class OrderViewSet(viewsets.ModelViewSet):

    serializer_class = OrderSerializer

    queryset = Orders.objects.all()

DefaultRouter在as的帮助下注册此视图,


from rest_framework.routers import DefaultRouter


router = DefaultRouter()

router.register(r'order', OrderViewSet, basename='order')

urlpatterns = [


              ] + router.urls

因此,您将获得该表中描述的基本 CRUD 端点(参见DefaultRouter参考文献)。

让您的订单列表端点成为/foo-bar/order/

  1. HTTP POST 来/foo-bar/order/创建一个新实例

  2. HTTP PUT 或 HTTP PATCH/foo-bar/order/<ORDER_PK>/以更新内容

笔记

在这种情况下,id如果您希望将现有的关系映射到Order

更新-1

您可以像这样连接视图


urlpatterns = [

    path('foo/order/', OrderViewSet.as_view({'post': 'create'})),  # create new Order instance

    path('foo/order/<int:pk>/', OrderViewSet.as_view({'patch': 'partial_update'})),  # update Order instance


]

注意:这仅支持HTTP POST和HTTP PATCH


查看完整回答
反对 回复 2022-11-01
  • 1 回答
  • 0 关注
  • 116 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信