Python Django RESTframework中模型字段的自动计算

Python Django RESTframework中模型字段的自动计算,python,django,django-rest-framework,Python,Django,Django Rest Framework,因此,我有一个模型,当api收到POST请求时,它有一个自动计算的属性。该模型是一个账单模型,其中总付款是根据numberOfHours*paymentRate计算的。Django不允许我通过设置默认值来执行此操作。有办法做到这一点吗 模型 序列化程序 class ReadBillSerializer(serializers.HyperlinkedModelSerializer): workAssignmentID_fk = ReadWorkAssignmentSerializer()

因此,我有一个模型,当api收到POST请求时,它有一个自动计算的属性。该模型是一个账单模型,其中总付款是根据numberOfHours*paymentRate计算的。Django不允许我通过设置默认值来执行此操作。有办法做到这一点吗

模型

序列化程序

class ReadBillSerializer(serializers.HyperlinkedModelSerializer):
    workAssignmentID_fk = ReadWorkAssignmentSerializer()

    class Meta:
        model = Bill
        fields = ('url', 'bill_dt', 'hours', 'workAssignmentID_fk', 'totalPayment')

class WriteBillSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Bill
        fields = ('url', 'bill_dt', 'hours', 'workAssignmentID_fk', 'totalPayment')
看法

在模型账单中,我想要totalPayment=hours*workAssignmentID\u fk.paymentRate

paymentRate是workAssignmentID_fk中的一个属性。

您可以覆盖视图中的函数,并将
totalPayment
的值传递给序列化程序的
save()
方法

保存新对象实例时调用
perform\u create()
。可以使用此对象创建挂钩

class BillViewSet(viewsets.ModelViewSet):
    queryset = Bill.objects.all()

    def get_serializer_class(self, *args, **kwargs):        
        if self.request.method == 'POST' or self.request.method == 'PUT':
            return WriteBillSerializer
        return ReadBillSerializer

    def perform_create(self, serializer):
        hours = serializer.validated_data['hours'] # get the value of hours
        work_assignment_object = <get_the_workAssignmentID_fk_object_from_passed_url>
        payment_rate = work_assignment_object.paymentRate # get the value of 'paymentRate' from work assignment object
        total_payment = hours*payment_rate # calculate value of total payment
        serializer.save(total_payment=total_payment, workAssignmentID_fk=work_assignment_object) # pass the value of total payment to be saved and the work assignment object
class BillViewSet(ViewSet.ModelViewSet):
queryset=Bill.objects.all()
def get_序列化程序_类(self、*args、**kwargs):
如果self.request.method==“POST”或self.request.method==“PUT”:
返回WriteBillSerializer
返回ReadBillSerializer
def执行_创建(自、序列化程序):
小时数=序列化程序。已验证的_数据['hours']#获取小时数的值
工作分配对象=
payment_rate=工作分配_object.paymentRate#从工作分配对象获取“paymentRate”的值
总付款=小时数*付款率#计算总付款的价值
serializer.save(total_payment=total_payment,workAssignmentID_fk=work_assignment_object)#传递要保存的total payment值和work assignment对象

请为序列化程序、模型和视图添加一些代码。是
numberofhours
paymentRate
模型字段吗?您正在使用模型序列化程序吗?感谢@RahulGupta的快速响应。我已经编辑了这个问题。请看一看,如果POST请求是在POST数据中传递的,我们如何获取
workAssignmentID\u fk
对象?如果是,是否还有
WorkAssignment
model的序列化程序?文章中的workAssignmentID\u fk只是指向对象的URL。例如,
http://API_URL/WorkAssignment/4/
但如果它是GET请求,它将以JSON子结构格式返回。因此,如果我在bill模型中有其他属性,我是否也必须在serializer.save方法中传递它们?您必须只传递那些您未
过帐
到视图的属性,以便将对象与所有必需的属性一起保存。我假设您在post数据中传递的不仅仅是2个字段
workAssignmentID\u fk
object和
totalPayment
,而是所有其他字段。因此,当保存对象时,它将从
.save()
kwargs中获取这两个字段,并从
序列化程序中获取其他字段。已验证的\u数据
。太好了!如果答案对你有用,别忘了接受。这可能会帮助其他有同样问题的人。:)
class BillViewSet(viewsets.ModelViewSet):
    queryset = Bill.objects.all()

    def get_serializer_class(self, *args, **kwargs):        
        if self.request.method == 'POST' or self.request.method == 'PUT':
            return WriteBillSerializer
        return ReadBillSerializer
class BillViewSet(viewsets.ModelViewSet):
    queryset = Bill.objects.all()

    def get_serializer_class(self, *args, **kwargs):        
        if self.request.method == 'POST' or self.request.method == 'PUT':
            return WriteBillSerializer
        return ReadBillSerializer

    def perform_create(self, serializer):
        hours = serializer.validated_data['hours'] # get the value of hours
        work_assignment_object = <get_the_workAssignmentID_fk_object_from_passed_url>
        payment_rate = work_assignment_object.paymentRate # get the value of 'paymentRate' from work assignment object
        total_payment = hours*payment_rate # calculate value of total payment
        serializer.save(total_payment=total_payment, workAssignmentID_fk=work_assignment_object) # pass the value of total payment to be saved and the work assignment object