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

2023-12-11

在我的 django 应用程序中,我之间存在多对多关系Orders and 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__"

Views.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 中的关系,所以请解释我是否需要更改模型或视图

Update:

我已经更新了我的序列化器以及视图以创建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

Views.py

class OrdersCreateAPIView(CreateAPIView):
    permission_classes = (permissions.IsAuthenticated,)
    serializer_class = OrderSerializer

    def perform_create(self,serializer):
        serializer.save(owner=self.request.user)

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

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


工作代码库

#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 ref).

让你订单终点为/foo-bar/order/

  1. HTTP POST 至/foo-bar/order/创建一个新实例
  2. HTTP PUT 或 HTTP PATCH 至/foo-bar/order/<ORDER_PK>/更新内容

Note

在这种情况下,您应该通过id如果您想映射现有的包的值package与的关系Order

参考

  1. DRF ModelVieSet
  2. Django get_or_create(...)
  3. Django create_or_update(...)
  4. Django M2M set(...)
  5. DRF DefaultRouter

UPDATE-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

]

Note:这仅支持HTTP POST and HTTP PATCH

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

更新 Django Rest Framework 中的多对多关系 的相关文章

随机推荐

  • 如何在C++中将较大的字符串减少为较小的字符串?可能是通过散列?

    我想在 C 中将较大的字符串压缩为较小的字符串 在 C 中执行此操作有哪些不同的方法 要求是输出也应该是字符串 好吧 如果您以后不需要解压缩它 string s xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx s E
  • 在 geom_密度_脊上画线

    我试图在 ggridges 的密度图中画一条线 library ggplot2 library ggridges ggplot iris aes x Sepal Length y Species geom density ridges re
  • 将 Excel 中的值除以一组预设值,以找出每个值需要多少个

    我很好奇是否有办法让我的生活更轻松 在 Excel 中 我生成一个总值 例如 750 并且需要从 50 100 200 250 500 的值中找出我需要多少个管道订单 无论如何 有没有办法让excel取一个值 然后返回我需要的每个数字的数量
  • 如何更改绘图标题和轴标签的字体大小并保存?

    每次我将绘图图片保存为 jpg 或 png 时 标题和轴标签的字体大小都会自动更改回默认值 我的代码是这样的 figure plot x f x title the smallest n 1 FontSize 24 xlabel x Fon
  • SQL排序不遵循group by语句,总是使用主键

    我有一个 SQL 数据库 其中有一个名为staff 具有以下列 workerID Prim key name department salary 我应该找到每个部门工资最高的工人 并使用以下语句 select staff workerID
  • ColdFusion CFHTTP 和 SSL 证书

    背景 当我尝试使用 CFHTTP 连接到 API 时 我一直遇到连接失败错误消息的问题 在查看 SoapUI 中的 API 时 我注意到有一个按钮SSL Info 3 certs 概述如下 当我单击该按钮时 会弹出一个副本窗口 其中概述了下
  • Android 设备 adb 在 linux/Mac 上始终未经授权

    我不得不处理这个问题几次 每次我都会忘记原因是什么 直到我深入挖掘 所以这是症状 每次重新连接 重新启动设备时 您都会收到授权对话框 即使您可以swear你检查了Always上次勾选了 adb shell给你下面的简介 adb device
  • 为什么在 C 中执行算术运算后会丢失值的余数?

    我正在尝试通过遵循以下内容来学习基本的 C 编程textbook我一定遗漏了一些关于数据类型 舍入和 或运算顺序的信息 因为当我尝试构建一个简单的程序将秒转换为小时和分钟时 小时有效 但剩余分钟在它们出现时变为 0不应该是 谢谢Course
  • 如何将外部 HTML 文件导入 TypeScript 类

    我正在尝试构建一个正在使用的 JavaScript 包Webpack将 TypeScript 文件及其所有导入编译为单个 JavaScript 文件 该包的主要目标是按照一组给定的条件向任何使用该包的应用程序输出 HTML 目前 我通过使用
  • Django Admin 中有“DetailView”吗?

    我知道 Django 管理中有一个更改 更新视图 但是是否有任何详细视图仅列出记录的属性 有点像 Django 应用程序中的 DetailView 或者有人知道我可以安装任何第三方软件包来提供相同的功能吗 我最近也在调查这个问题 一种有效的
  • 查询 JSON 列中数组的元素

    最近升级到使用 PostgreSQL 9 3 1 来利用 JSON 功能 在我的表中 我有一个 json 类型列 其结构如下 id 123 name foo emails id 123 address somethinghere id 45
  • 对数组进行排序的最小“插入”次数

    假设有一个无序列表 我们唯一能做的操作就是移动一个元素并将其插入回任何位置 对整个列表进行排序需要多少步 我想答案是size of the list size of longest ordered sequence 但我不知道如何证明这一点
  • 在 Swift 中使用 GeoFire 查询不会提供有用的输出

    我现在非常绝望 因为我正在尝试在 Firebase 数据库上使用 GeoFire 来查找附近的用户 我现在已经被困了两天了 我在 Google 和 stackoverflow 上进行了很多搜索 并尝试了在那里找到的所有内容 但没有成功 现在
  • 黑莓 - 自定义尺寸 EditField

    我正在尝试组合一个应该如下所示的对话框 填写以下字段 喜欢 其中 行是编辑字段 我将所有字段粘贴到 Horizo ntalFieldManager 中 并将其添加到对话框中 不幸的是 第一个 EditField 占用了第一行的所有空间 我尝
  • 未找到名为 zlib 的模块

    我下载python2 6 6源码形式http www python org getit releases 2 6 6 之后我运行这些命令 配置 制作 我尝试导入 zlib 但它说没有名为 zlib 的模块 如何为其安装 zlib 模块 在我
  • tkinter 中是否可以有一个垂直方向的按钮?

    是否可以定向tk Button or ttk Button垂直 就像定向一个tk Scrollbar在某种方式self scrlbr tk Scrollbar master orient vertical 试过tk Button args
  • Python Tkinter:如何配置循环生成的按钮?

    我正在使用 Python 2 7 和 Tkinter 为我的代码制作 GUI 在某一时刻 框架中充满了许多循环按钮 当我单击其中一个按钮时 该函数需要知道它是从哪里调用的 所以我在谷歌上搜索并找到了这种很好的方法 def generate
  • 线程“AWT-EventQueue-0”中的异常 java.lang.NoClassDefFoundError

    我正在尝试阅读 docx文件到一个JTextPane 但它给出了一些例外 我在用POI图书馆 我应该怎么办 请帮帮我 这是我的代码 file new File C Users Siddique Ansari Documents CV Par
  • 尝试为 Windows 扩展安装 Python 时出现值错误

    我已经安装了 Microsoft Visual Studio 2008 我下载了 zip 文件用于 Windows 的 Python 扩展并将内容提取到我的 Python27 文件夹中 现在有一个名为 pywin32 214 的子文件夹 3
  • 更新 Django Rest Framework 中的多对多关系

    在我的 django 应用程序中 我之间存在多对多关系Orders and Packages 一个订单可以有多个包裹 我想了解更新和创建方法 模型 py class Package models Model prod name models