Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django rest framework 在框架中创建模型实例之前操作序列化程序上的数据_Django Rest Framework_Python 3.6 - Fatal编程技术网

Django rest framework 在框架中创建模型实例之前操作序列化程序上的数据

Django rest framework 在框架中创建模型实例之前操作序列化程序上的数据,django-rest-framework,python-3.6,Django Rest Framework,Python 3.6,我有三个相关的模型 订单模型 订单定价模型 订单类型模型 让我们忽略上面模型的显示顺序 每个模型有三个序列化模型 我可以在BrowsableAPI上对每个模型进行crud 问题1: 我可以从浏览器中创建订单 我还没有找到“可写的嵌套序列化程序”,我相信Django已经通过drf可写的嵌套类在他们的文档中找到了这一点 我有两种订单类型 1={'Not Premium':'False'}Not Premium 2={'Premium':'True'}#Premium 假设我有一个变量订单价格=5英镑

我有三个相关的模型

订单模型

订单定价模型

订单类型模型

  • 让我们忽略上面模型的显示顺序
  • 每个模型有三个序列化模型
  • 我可以在BrowsableAPI上对每个模型进行crud
  • 问题1:

    我可以从浏览器中创建订单

    我还没有找到“可写的嵌套序列化程序”,我相信Django已经通过drf可写的嵌套类在他们的文档中找到了这一点

    我有两种订单类型

    1={'Not Premium':'False'}Not Premium

    2={'Premium':'True'}#Premium

    假设我有一个变量订单价格=5英镑

    我怎么能

  • 创建订单
  • 如果订单为特价,则将订单价格设置为10#订单价格*2
  • 如果订单不是特价,则将订单价格设置为5
  • 创建与订单相关的OrderPricing实例。另外,在创建实例时,将order\u price变量传递给属性TotalPrice
  • 根据我的所见所闻和尝试,我可以重写序列化程序上的Create()

    class OrderSerializer(WritableNestedModelSerializer):
        """OrderSerializer"""
        # orderPricing = OrderPricingSerializer(required=False)
    
        class Meta:
            model = Order
            fields = ('__all__')
    
        def create(self, validated_data):
            #create instance of order
            #determine of order is premium
            typeid = uuid.UUID(validated_data.pop('orderType'))#get FK value
            isPremium = OrderType.objects.get(id = str(typeid.id))#determine if **Premium** is True/False
    
            # set/calculate the price of the order
            #create a related instance of OrderPricing
    
    问题2 我知道GenericView和CreateModelMixin,但我不知道哪一个更好,在序列化程序中重写.create(),还是在GenericView中重写CreateModelMixin方法


    那么,业务逻辑放在哪里总是一个很难回答的问题。 您可以在多个位置使用它—视图、序列化程序、模型或其他一些单独的模块/服务

    所有这些都有优点和缺点——你可以找到许多关于这个主题的文章

    但在您的情况下,我可能会使用您视图的
    perform\u create
    ,并在序列化程序中创建一个方法来更新价格。如果我需要使用代码来更新price,我会移动到单独的共享模块并从那里调用它

    假设您使用
    CreateModelMixin
    或更好的
    ListCreateAPIView

    class YourView(ListCreateAPIView):
        serializer = OrderSerializer
        queryset = your_queryset
    
        def perform_create(self, serializer):
             serializer.update_price()
             serializer.save()
    
    验证数据后会调用
    perform\u create
    ,因此您可以访问已验证的数据

    update\u price
    是您更新价格的代码

    您可以主张将此逻辑移动到序列化程序的create或save方法,但它们会执行许多其他操作,因此,除非您出于其他原因需要重写这些方法,否则您可以利用
    perform\u create
    方法

    class OrderType(models.Model):
        id = models.UUIDField(primary_key=True, default=uuid.uuid4)
        Name = models.CharField(max_length = 100)
        Premium =  models.BooleanField()
    
        class Meta:
            ordering = ['id']
    
    class OrderSerializer(WritableNestedModelSerializer):
        """OrderSerializer"""
        # orderPricing = OrderPricingSerializer(required=False)
    
        class Meta:
            model = Order
            fields = ('__all__')
    
        def create(self, validated_data):
            #create instance of order
            #determine of order is premium
            typeid = uuid.UUID(validated_data.pop('orderType'))#get FK value
            isPremium = OrderType.objects.get(id = str(typeid.id))#determine if **Premium** is True/False
    
            # set/calculate the price of the order
            #create a related instance of OrderPricing
    
    class YourView(ListCreateAPIView):
        serializer = OrderSerializer
        queryset = your_queryset
    
        def perform_create(self, serializer):
             serializer.update_price()
             serializer.save()