Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.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
Python ListCreateAPIView创建一个新对象,即使该对象已经存在。Django Rest框架_Python_Django_Django Rest Framework - Fatal编程技术网

Python ListCreateAPIView创建一个新对象,即使该对象已经存在。Django Rest框架

Python ListCreateAPIView创建一个新对象,即使该对象已经存在。Django Rest框架,python,django,django-rest-framework,Python,Django,Django Rest Framework,我正在创建一个API,它将返回付款期和费用报告。我有一个存储所有必要信息的工单模型,我在项目中创建了一个reports应用程序,它使用SerializerMethodField返回我需要的计算。我的问题是,如果我使用存在对象的字段中的数据发出post请求,它将创建一个新对象。我正在使用ListCreateAPIView,据我所知,如果对象已经存在,它应该检索该对象。我错过了什么?谢谢你的阅读 models.py class PayPeriodReport(models.Model): t

我正在创建一个API,它将返回付款期和费用报告。我有一个存储所有必要信息的工单模型,我在项目中创建了一个reports应用程序,它使用SerializerMethodField返回我需要的计算。我的问题是,如果我使用存在对象的字段中的数据发出post请求,它将创建一个新对象。我正在使用ListCreateAPIView,据我所知,如果对象已经存在,它应该检索该对象。我错过了什么?谢谢你的阅读

models.py

class PayPeriodReport(models.Model):
    tech = models.ForeignKey(Employee, null=True, on_delete=models.CASCADE, 
related_name='employee')
    start_date = models.DateField()
    end_date = models.DateField()
url.py

    urlpatterns = [
    path('payperiodreport/<employee>/<start_date>/<end_date>', views.PayPeriodReportView.as_view(), name='payperiod-report')
]
序列化程序.py

class PayPeriodReportSerializer(serializers.ModelSerializer):

    break_down = serializers.SerializerMethodField()

    class Meta:
        model = PayPeriodReport
        fields = '__all__'


    # Get all work orders associated with report
    def get_all_workorders(self, obj):
        return WorkOrder.objects.filter(tech=obj.tech, start_date__range=(obj.start_date, obj.end_date))

    # Get days as a list of strings to be used as keys in dictinoary.
    def get_list_of_days(self, obj):
        days = obj.end_date - obj.start_date
        return [obj.start_date + timedelta(days=time) for time in range(days.days +1)]

    # returns a list of the week numbers to be used in weekly breakdown dictinoary.
    def get_payperiod_weeks(self, obj):
        days = obj.end_date - obj.start_date
        week_breakdown = {'weekly_total': timedelta(0), 'weekly_overtime': timedelta(0), 'weekly_regular': timedelta(0)}
        return list(dict.fromkeys([day.isocalendar()[1] for day in [obj.start_date + timedelta(days=time) for time in range(days.days +1)]]))

    # Returns dates of the week that the start date is in.  So that they can be checked for weekly overtime.
    def get_first_week_dates(self, obj):
        last_day_of_week = obj.start_date + timedelta(days=(6-obj.start_date.weekday()))
        first_day_of_week = last_day_of_week - timedelta(days=6)
        return[first_day_of_week + timedelta(days=time) for time in range(7)]



    # Return a dictionary with the following structure
    # break_down{daily_breakdown:
    #                    {date: {
    #                            days_workorders: [],
    #                            daily_total: total time for days workorders,
    #                            daily_regular: total non overtime time on workorders,
    #                             daily_overtime: total overtime on workorders,
    #                             },
    #            weekly_breakdown:{week:{total_overtime: , total_time: , total_regular:}}
    #            total_overtime: total overtime for entire report,
    #            total_regular: total regular time for report,
    #            total_time: total time for report,
    #                                     }
    #

    def get_break_down(self, obj):
        workorders = self.get_all_workorders(obj)
        days = self.get_list_of_days(obj)
        pay_period_weeks = self.get_payperiod_weeks(obj)
        total_hours = total_overtime = total_regular = timedelta(0)
        break_down = {'daily_breakdown': {}, 'weekly_breakdown': {}}
        weekly_breakdown = {}
        first_week = self.get_first_week_dates(obj)
        #To know when to stop calculating first weeks overtime.
        last_day_of_week = first_week[-1]
        #To access week
        first_week_key = first_week[0].isocalendar()[1]
        #Variable to store total of work orders for first week that are on selected pay period
        first_pay_period_week_total = timedelta(0)
        #Variable to store total of work orders for all of first week, including days not on selected pay period
        first_week_of_payperiod_total = timedelta(0)

        #Add week numbers as keys to dictinoaries
        for week in pay_period_weeks:
            weekly_breakdown[week] = {'weekly_total': timedelta(0), 'weekly_regular': timedelta(0), 'weekly_overtime': timedelta(0)}


        for day in days:
            #Checks that there were any work orders that day.
            if sum([workorder.id for workorder in workorders if day == workorder.start_date]):
                daily_breakdown = {}
                daily_breakdown['days_workorders'] = [workorder.WO_number for workorder in workorders if day == workorder.start_date]
                # Reset variables at start of loop
                daily_total = daily_overtime = daily_regular = timedelta(0)
                #Convert date to string so it can be used as a key
                date = day.strftime('%x')
                weekly_total = timedelta(0)
                for workorder in [workorder for workorder in workorders if day == workorder.start_date]:
                    daily_total += (workorder.end_time - workorder.start_time - workorder.non_billable_total)
                    if workorder.start_date.isocalendar()[1] != first_week_key:
                        weekly_breakdown[workorder.start_date.isocalendar()[1]]['weekly_total'] += (workorder.end_time - workorder.start_time - workorder.non_billable_total)
                # Add daily total to dictionary for that day
                daily_breakdown['daily_total'] = daily_total/3600
                #Add daily overtime and regular time to dictionary
                if daily_total > timedelta(hours=8):
                    daily_breakdown['daily_overtime'] = (daily_total - timedelta(hours=8))/3600
                    daily_breakdown['daily_regular'] = timedelta(hours=8)/3600
                else:
                    daily_breakdown['daily_overtime'] = timedelta(0)
                    daily_breakdown['daily_regular'] = daily_total/3600

                break_down['daily_breakdown'][date] = daily_breakdown
            else:
                pass

        #Checks first week for weekly overtime
        for day in first_week:
            for workorder in workorders:
                if day == workorder.start_date:
                    first_week_of_payperiod_total += (workorder.end_time - workorder.start_time - workorder.non_billable_total)
                    if day >= obj.start_date and day <= last_day_of_week:
                        first_pay_period_week_total += (workorder.end_time - workorder.start_time - workorder.non_billable_total)

        if first_week_of_payperiod_total > timedelta(hours=40):
            weekly_breakdown[first_week_key]['weekly_overtime'] = (first_week_of_payperiod_total - timedelta(hours=40))/3600
            weekly_breakdown[first_week_key]['weekly_regular'] = (first_pay_period_week_total/3600 - weekly_breakdown[first_week_key]['weekly_overtime'])
            weekly_breakdown[first_week_key]['weekly_total'] = first_week_of_payperiod_total /3600
        else:
            weekly_breakdown[first_week_key]['weekly_regular'] = first_pay_period_week_total/3600

        #Starts at index 1 to check the rest of the weeks.
        for week in range(1,(len(pay_period_weeks))):
            if weekly_breakdown[pay_period_weeks[week]]['weekly_total'] > timedelta(hours=40):
                weekly_breakdown[pay_period_weeks[week]]['weekly_overtime'] =  (weekly_breakdown[pay_period_weeks[week]]['weekly_total'] - timedelta(hours=40)) / 3600
                weekly_breakdown[pay_period_weeks[week]]['weekly_regular'] = weekly_breakdown[pay_period_weeks[week]]['weekly_total']/3600 - weekly_breakdown[pay_period_weeks[week]]['weekly_overtime']
                weekly_breakdown[pay_period_weeks[week]]['weekly_total'] = weekly_breakdown[pay_period_weeks[week]]['weekly_total']/3600
            else:
                weekly_breakdown[pay_period_weeks[week]]['weekly_regular'] = weekly_breakdown[pay_period_weeks[week]]['weekly_total']
                weekly_breakdown[pay_period_weeks[week]]['weekly_total'] = weekly_breakdown[pay_period_weeks[week]]['weekly_total']/3600

        break_down['weekly_breakdown'] = weekly_breakdown

        value_sums = lambda inner_key: reduce(lambda x, y: x + y, [break_down['daily_breakdown'][key][inner_key] for key in break_down['daily_breakdown'].keys()]) if [break_down['daily_breakdown'][key][inner_key] for key in break_down['daily_breakdown'].keys()] else timedelta(0)
        break_down['total_overtime'] = value_sums('daily_overtime')
        break_down['total_regular'] = value_sums('daily_regular')
        break_down['total_time'] = break_down['total_regular'] + break_down['total_overtime']

        return(break_down)
class PayPeriodReportSerializer(serializers.ModelSerializer):
break\u down=serializers.SerializerMethodField()
类元:
模型=付款周期报告
字段='\uuuu所有\uuuu'
#获取与报表关联的所有工单
def获取所有工作订单(自我、obj):
return WorkOrder.objects.filter(tech=obj.tech,start\u date\u range=(obj.start\u date,obj.end\u date))
#获取天数作为要在字典中用作键的字符串列表。
def获取天数列表(自我、obj):
天数=对象结束日期-对象开始日期
返回[obj.start_date+timedelta(days=time),表示范围内的时间(days.days+1)]
#返回要在每周细分词汇表中使用的周数列表。
def领取工资期周(自我、obj):
天数=对象结束日期-对象开始日期
周分解={'weekly\u total':timedelta(0),'weekly\u加班时间]:timedelta(0),'weekly\u regular':timedelta(0)}
返回列表(dict.fromkeys([day.isocalendar()[1]表示范围内时间(days.days+1)]的[obj.start\u date+timedelta(days=time)中的日期)
#返回开始日期所在周的日期。这样他们就可以每周加班检查。
def获取第一周日期(自我、obj):
上周的最后一天=obj.start\u日期+时间差(天=(6-obj.start\u日期.工作日())
每周第一天=每周最后一天-时间差(天=6)
对于范围(7)内的时间,返回[每周的第一天+时间增量(天=时间)]
#返回具有以下结构的词典
#细分{每日细分:
#{日期:{
#天数\工作顺序:[],
#每日总时间:每天工作订单的总时间,
#每日定期:工作单上的非加班总时间,
#每日加班:工作单上的总加班,
#                             },
#每周工作分解:{每周:{加班总时间:,总时间:,总常规时间:}
#总加班时间:整个报告的总加班时间,
#总定期:报告的总定期时间,
#总时间:报告的总时间,
#                                     }
#
def获取故障(自我、obj):
工单=自我。获取所有工单(obj)
天数=自我。获取天数列表(obj)
支付周期周=自我获取支付周期周(obj)
总工时=总加班=总定期=时间增量(0)
分解={'每日分解':{},'每周分解':{}
每周_细分={}
第一周=自我。获取第一周日期(obj)
#知道何时停止计算第一周的加班时间。
上周的最后一天=第一周[-1]
#访问星期
第一周密钥=第一周[0]。isocalendar()[1]
#变量,用于存储选定付款期第一周的工单总数
首次付款期周总数=时间差(0)
#变量,用于存储所有第一周的工单总数,包括不在所选付款期的天数
支付期的第一周总计=时间差(0)
#将周数添加为字典的键
对于支付期内的周:
每周工作分解[周]={'weekly\u total':timedelta(0),'weekly\u regular':timedelta(0),'weekly\u加班时间]:timedelta(0)}
对于以天为单位的天:
#检查当天是否有任何工作指令。
if sum([workorder.id for workorder in workorder if day==workorder.start_date]):
每日_细分={}
每日\u细分['days\u workorder']=[workorder.WO\u如果day==workorder.start\u日期,则为workorder中的workorder编号]
#在循环开始时重置变量
每日总计=每日加班=每日定期=时间增量(0)
#将日期转换为字符串,以便将其用作键
日期=天。strftime(“%x”)
每周总计=时间增量(0)
对于[workorder中的workorder for workorder in workorder if day==workorder.start\u date]中的workorder]:
每日\总计+=(工作订单。结束\时间-工作订单。开始\时间-工作订单。非计费总计)
如果workorder.start\u date.isocalendar()[1]!=第一周密钥:
每周分解[工作顺序.开始日期.等Calendar()[1][“每周总计”]+=(工作顺序.结束时间-工作顺序.开始时间-工作顺序.非计费总计)
#将当天的每日总计添加到字典中
每日细目[每日总计]=每日总计/3600
#将每日加班和正常时间添加到字典中
如果每日总时间>时间增量(小时=8):
每日工作时间细分['daily\u加班]=(每日工作时间总计-时间增量(小时=8))/3600
每日细分['daily\u regular']=timedelta(小时=8)/3600
其他:
每日加班次数['daily\u externation']=timedelta(0)
每日细分[每日常规]=每日总计/3600
分解[每日分解][日期]=每日分解
其他:
通过
#检查第一周是否每周加班
对于第一周中的一天:
对于工单中的工单:
如果日期==工单开始日期:
class PayPeriodReportSerializer(serializers.ModelSerializer):

    break_down = serializers.SerializerMethodField()

    class Meta:
        model = PayPeriodReport
        fields = '__all__'


    # Get all work orders associated with report
    def get_all_workorders(self, obj):
        return WorkOrder.objects.filter(tech=obj.tech, start_date__range=(obj.start_date, obj.end_date))

    # Get days as a list of strings to be used as keys in dictinoary.
    def get_list_of_days(self, obj):
        days = obj.end_date - obj.start_date
        return [obj.start_date + timedelta(days=time) for time in range(days.days +1)]

    # returns a list of the week numbers to be used in weekly breakdown dictinoary.
    def get_payperiod_weeks(self, obj):
        days = obj.end_date - obj.start_date
        week_breakdown = {'weekly_total': timedelta(0), 'weekly_overtime': timedelta(0), 'weekly_regular': timedelta(0)}
        return list(dict.fromkeys([day.isocalendar()[1] for day in [obj.start_date + timedelta(days=time) for time in range(days.days +1)]]))

    # Returns dates of the week that the start date is in.  So that they can be checked for weekly overtime.
    def get_first_week_dates(self, obj):
        last_day_of_week = obj.start_date + timedelta(days=(6-obj.start_date.weekday()))
        first_day_of_week = last_day_of_week - timedelta(days=6)
        return[first_day_of_week + timedelta(days=time) for time in range(7)]



    # Return a dictionary with the following structure
    # break_down{daily_breakdown:
    #                    {date: {
    #                            days_workorders: [],
    #                            daily_total: total time for days workorders,
    #                            daily_regular: total non overtime time on workorders,
    #                             daily_overtime: total overtime on workorders,
    #                             },
    #            weekly_breakdown:{week:{total_overtime: , total_time: , total_regular:}}
    #            total_overtime: total overtime for entire report,
    #            total_regular: total regular time for report,
    #            total_time: total time for report,
    #                                     }
    #

    def get_break_down(self, obj):
        workorders = self.get_all_workorders(obj)
        days = self.get_list_of_days(obj)
        pay_period_weeks = self.get_payperiod_weeks(obj)
        total_hours = total_overtime = total_regular = timedelta(0)
        break_down = {'daily_breakdown': {}, 'weekly_breakdown': {}}
        weekly_breakdown = {}
        first_week = self.get_first_week_dates(obj)
        #To know when to stop calculating first weeks overtime.
        last_day_of_week = first_week[-1]
        #To access week
        first_week_key = first_week[0].isocalendar()[1]
        #Variable to store total of work orders for first week that are on selected pay period
        first_pay_period_week_total = timedelta(0)
        #Variable to store total of work orders for all of first week, including days not on selected pay period
        first_week_of_payperiod_total = timedelta(0)

        #Add week numbers as keys to dictinoaries
        for week in pay_period_weeks:
            weekly_breakdown[week] = {'weekly_total': timedelta(0), 'weekly_regular': timedelta(0), 'weekly_overtime': timedelta(0)}


        for day in days:
            #Checks that there were any work orders that day.
            if sum([workorder.id for workorder in workorders if day == workorder.start_date]):
                daily_breakdown = {}
                daily_breakdown['days_workorders'] = [workorder.WO_number for workorder in workorders if day == workorder.start_date]
                # Reset variables at start of loop
                daily_total = daily_overtime = daily_regular = timedelta(0)
                #Convert date to string so it can be used as a key
                date = day.strftime('%x')
                weekly_total = timedelta(0)
                for workorder in [workorder for workorder in workorders if day == workorder.start_date]:
                    daily_total += (workorder.end_time - workorder.start_time - workorder.non_billable_total)
                    if workorder.start_date.isocalendar()[1] != first_week_key:
                        weekly_breakdown[workorder.start_date.isocalendar()[1]]['weekly_total'] += (workorder.end_time - workorder.start_time - workorder.non_billable_total)
                # Add daily total to dictionary for that day
                daily_breakdown['daily_total'] = daily_total/3600
                #Add daily overtime and regular time to dictionary
                if daily_total > timedelta(hours=8):
                    daily_breakdown['daily_overtime'] = (daily_total - timedelta(hours=8))/3600
                    daily_breakdown['daily_regular'] = timedelta(hours=8)/3600
                else:
                    daily_breakdown['daily_overtime'] = timedelta(0)
                    daily_breakdown['daily_regular'] = daily_total/3600

                break_down['daily_breakdown'][date] = daily_breakdown
            else:
                pass

        #Checks first week for weekly overtime
        for day in first_week:
            for workorder in workorders:
                if day == workorder.start_date:
                    first_week_of_payperiod_total += (workorder.end_time - workorder.start_time - workorder.non_billable_total)
                    if day >= obj.start_date and day <= last_day_of_week:
                        first_pay_period_week_total += (workorder.end_time - workorder.start_time - workorder.non_billable_total)

        if first_week_of_payperiod_total > timedelta(hours=40):
            weekly_breakdown[first_week_key]['weekly_overtime'] = (first_week_of_payperiod_total - timedelta(hours=40))/3600
            weekly_breakdown[first_week_key]['weekly_regular'] = (first_pay_period_week_total/3600 - weekly_breakdown[first_week_key]['weekly_overtime'])
            weekly_breakdown[first_week_key]['weekly_total'] = first_week_of_payperiod_total /3600
        else:
            weekly_breakdown[first_week_key]['weekly_regular'] = first_pay_period_week_total/3600

        #Starts at index 1 to check the rest of the weeks.
        for week in range(1,(len(pay_period_weeks))):
            if weekly_breakdown[pay_period_weeks[week]]['weekly_total'] > timedelta(hours=40):
                weekly_breakdown[pay_period_weeks[week]]['weekly_overtime'] =  (weekly_breakdown[pay_period_weeks[week]]['weekly_total'] - timedelta(hours=40)) / 3600
                weekly_breakdown[pay_period_weeks[week]]['weekly_regular'] = weekly_breakdown[pay_period_weeks[week]]['weekly_total']/3600 - weekly_breakdown[pay_period_weeks[week]]['weekly_overtime']
                weekly_breakdown[pay_period_weeks[week]]['weekly_total'] = weekly_breakdown[pay_period_weeks[week]]['weekly_total']/3600
            else:
                weekly_breakdown[pay_period_weeks[week]]['weekly_regular'] = weekly_breakdown[pay_period_weeks[week]]['weekly_total']
                weekly_breakdown[pay_period_weeks[week]]['weekly_total'] = weekly_breakdown[pay_period_weeks[week]]['weekly_total']/3600

        break_down['weekly_breakdown'] = weekly_breakdown

        value_sums = lambda inner_key: reduce(lambda x, y: x + y, [break_down['daily_breakdown'][key][inner_key] for key in break_down['daily_breakdown'].keys()]) if [break_down['daily_breakdown'][key][inner_key] for key in break_down['daily_breakdown'].keys()] else timedelta(0)
        break_down['total_overtime'] = value_sums('daily_overtime')
        break_down['total_regular'] = value_sums('daily_regular')
        break_down['total_time'] = break_down['total_regular'] + break_down['total_overtime']

        return(break_down)
tech = models.ForeignKey(Employee, null=True,  on_delete=models.CASCADE, related_name='employee', unique=True)