在DangoRestFramework中创建模型实例之前,请在序列化程序上处理数据

时间:2018-11-01 19:37:25

标签: django-rest-framework python-3.6

我有三个相关的模型

  

订单模型

class Order(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    Name  =  models.CharField(max_length=250)
    orderType = models.ForeignKey(OrderType, on_delete=models.CASCADE, null=True)

    class Meta:
        ordering = ['id']
    def __str__(self):
        return '{}'.format(self.Name)enter code here
  

OrderPricing模型

class OrderPricing(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    TotalPrice =  models.DecimalField(decimal_places=2, max_digits=10)
    #related field
    order = models.ForeignKey(Order, on_delete=models.CASCADE, null=True)

    class Meta:
        ordering = ['order']
    def __str__(self):
        return self.TotalPrice
  

OrderType模型

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']
  1. 让我们忽略模型在上面显示的顺序。
  2. 每个模型都有三个SerializerModels。
  3. 我可以在BrowsableAPI上创建每个模型

第一季度:

我可以从browsableAPI创建一个订单。

我还没有接触过“可写嵌套序列化器”,我相信Django通过drf-writable-nested类在文档中已经指出了这一点。

我有两个ord​​erTypes

1 = {'非高级':'假'}#非高级

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

  

假设我有一个变量 order_price = 5#£5

     

我怎么

  1. 创建订单
  2. 如果订单溢价,则将order_price设置为10 #order_price * 2
  3. 如果订单不是优质订单,则将order_price设置为5
  4. 创建与订单相关的OrderPricing实例。此外,在创建实例时,将 order_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
  

第二季度   我知道GenericViews和CreateModelMixin,我不知道的是,更好的是,在序列化程序中重写.create()或在GenericView中重写CreateModelMixin方法

1 个答案:

答案 0 :(得分:1)

好吧,将业务逻辑放在何处总是很难回答的问题。 您可以在多个地方使用它-视图,序列化器,模型或其他一些单独的模块/服务。

每个人都有优点和缺点-您可以找到许多与此主题相关的文章。

但是在您的情况下,我可能会使用您的视图的perform_create,并且会在序列化器中创建一个方法来更新价格。如果我需要使用代码来更新价格,我将移至单独的共享模块并从那里调用它。

因此,假设您使用CreateModelMixin或更佳的ListCreateAPIView

class YourView(ListCreateAPIView):
    serializer = OrderSerializer
    queryset = your_queryset

    def perform_create(self, serializer):
         serializer.update_price()
         serializer.save()
验证数据后,将调用

perform_create,因此您可以访问验证的数据。

update_price是您更新价格的代码。

您可以争辩说要将此逻辑移到序列化器的create或save方法中,但是它们还会做很多其他事情,因此除非您出于其他原因需要覆盖这些方法,否则可以利用perform_create方法。