如何在Django / Python中获得倒数第二个最近的时间戳记录?

我有一个模型的表单,该表单跟踪输入/离开时间。我正在尝试添加约束以使数据更准确。当前,当有人“输入”时,它将创建一条记录,将时间保存在“ time_in” DateTimeField中,然后进行重定向。如果此人然后尝试再次输入,它将创建带有新时间戳记的新记录。

我现在要添加的是,如果此人的上一个条目没有退出时间戳(time_out),则该记录(将是倒数第二个最近的条目)将通过更新 time_exceptions 字段设置为“ N”。

当前,无论是否存在出口,它都会将所有字段都更改为“ N”,如下所示。

注意,我减少了form_valid中的代码量,因此请假区域不存在。只是基于其他字段的大量筛选,而且似乎不太相关。

views.py

class EnterExitArea(CreateView):
    model = EmployeeWorkAreaLog
    template_name = "operations/enter_exit_area.html"
    form_class = WarehouseForm

    def form_valid(self,form):
        emp_num = form.cleaned_data['employee_number']
        area = form.cleaned_data['work_area']
        station = form.cleaned_data['station_number']

        if 'enter_area' in self.request.POST:
            form.save()
            EmployeeWorkAreaLog.objects.filter((Q(employee_number=emp_num) & Q(work_area=area) & Q(time_out__isnull=True) & Q(time_in__isnull=True)) & (Q(station_number=station) | Q(station_number__isnull=True))).update(time_in=datetime.now())

            if EmployeeWorkAreaLog.objects.filter(Q(employee_number=emp_num)).count() > 1:
                EmployeeWorkAreaLog.objects.filter((Q(employee_number=emp_num) & Q(work_area=area) & Q(time_out__isnull=True)) & (Q(station_number=station) | Q(station_number__isnull=True))).update(time_exceptions='N')

            return HttpResponseRedirect(self.request.path_info)

我尝试了以下操作,但是得到了expected string or bytes-like object,尽管它在崩溃前仍会创建一条新记录,但它不会将第二个的time_exceptions更新为N。

        if 'enter_area' in self.request.POST:
            form.save()
            EmployeeWorkAreaLog.objects.filter((Q(employee_number=emp_num) & Q(work_area=area) & Q(time_out__isnull=True) & Q(time_in__isnull=True)) & (Q(station_number=station) | Q(station_number__isnull=True))).update(time_in=datetime.now())

            if EmployeeWorkAreaLog.objects.filter(Q(employee_number=emp_num) & Q(time_out__isnull=True) & Q(time_exceptions="")).count() > 1:
                recent = EmployeeWorkAreaLog.objects.filter(employee_number=emp_num,work_area=area,station_number=station,time_out__isnull=True).order_by('-time_in')[1]

                EmployeeWorkAreaLog.objects.filter((Q(employee_number=emp_num) & Q(work_area=area) & Q(time_in=recent) & Q(time_out__isnull=True)) & (Q(station_number=station) | Q(station_number__isnull=True))).update(time_exceptions='N')

            return HttpResponseRedirect(self.request.path_info)

models.py

class EmployeeWorkAreaLog(TimeStampedmodel,SoftDeleteModel,models.Model):
    employee_number = models.ForeignKey(Salesman,on_delete=models.SET_NULL,help_text="Employee #",null=True,blank=False)
    work_area = models.ForeignKey(WorkArea,blank=False,help_text="Work Area",related_name="work_area")
    station_number = models.ForeignKey(StationNumber,time_exceptions = models.CharField(max_length=2,blank=True)
    time_in = models.DateTimeField(help_text="Time in",blank=True)
    time_out = models.DateTimeField(blank=True,help_text="Time out",null=True)

    def __str__(self):
        return self.employee_number

回溯:

Internal Server Error: /operations/enter-exit-area/
Traceback (most recent call last):
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\core\handlers\exception.py",line 34,in inner
    response = get_response(request)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\core\handlers\base.py",line 126,in _get_response
    response = self.process_exception_by_middleware(e,request)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\core\handlers\base.py",line 124,in _get_response
    response = wrapped_callback(request,*callback_args,**callback_kwargs)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\views\generic\base.py",line 68,in view
    return self.dispatch(request,*args,**kwargs)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\views\generic\base.py",line 88,in dispatch
    return handler(request,**kwargs)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\views\generic\edit.py",line 172,in post
    return super().post(request,line 142,in post
    return self.form_valid(form)
  File "C:\Users\mkusneco\apps.rsrgroup.com\apps\operations\views.py",line 45,in form_valid
    Q(station_number=station) | Q(station_number__isnull=True))).update(time_exceptions='N')
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\manager.py",line 82,in manager_method
    return getattr(self.get_queryset(),name)(*args,**kwargs)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\query.py",line 844,in filter
    return self._filter_or_exclude(False,line 862,in _filter_or_exclude
    clone.query.add_q(Q(*args,**kwargs))
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\sql\query.py",line 1263,in add_q
    clause,_ = self._add_q(q_object,self.used_aliases)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\sql\query.py",line 1281,in _add_q
    current_negated,allow_joins,split_subq)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\sql\query.py",line 1287,in _add_q
    split_subq=split_subq,File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\sql\query.py",line 1225,in build_filter
    condition = self.build_lookup(lookups,col,value)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\sql\query.py",line 1096,in build_lookup
    lookup = lookup_class(lhs,rhs)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\lookups.py",line 20,in __init__
    self.rhs = self.get_prep_lookup()
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\lookups.py",line 70,in get_prep_lookup
    return self.lhs.output_field.get_prep_value(self.rhs)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\fields\__init__.py",line 1408,in get_prep_value
    value = super().get_prep_value(value)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\fields\__init__.py",line 1268,in get_prep_value
    return self.to_python(value)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\db\models\fields\__init__.py",line 1369,in to_python
    parsed = parse_datetime(value)
  File "C:\Users\mkusneco\appsve\lib\site-packages\django\utils\dateparse.py",line 106,in parse_datetime
    match = datetime_re.match(value)
TypeError: expected string or bytes-like object
oejdhoigfiugfiug 回答:如何在Django / Python中获得倒数第二个最近的时间戳记录?

您为EmployeeWorkAreaLog分配了一个recent实例,但是您将其用作条件Q(time_in=recent),这显然是错误的,因为条件需要包含一个简单的值/ datetime /字符串,而不是对象。

因此,您可以通过使用Q(time_in=recent.time_in)对其进行修复,但是如果用户有某种重复的条目,这并不是很可靠。使用实例的pk更好的,因此,您可以使用time_in来代替Q(pk=recent.pk)条件。但这仍然不是最佳解决方案-如果有多个这样的条目怎么办?为什么只更新第二个而不更新第三个,等等?

因此,我认为应该选择第一个而不是选择第二个条目(使用[1]),然后从更新查询集中将其排除,例如:

first = EmployeeWorkAreaLog.objects.filter(employee_number=emp_num,work_area=area,station_number=station,time_out__isnull=True).order_by('-time_in').first()
EmployeeWorkAreaLog.objects.filter((Q(employee_number=emp_num) & Q(work_area=area) & Q(time_out__isnull=True)) & (Q(station_number=station) | Q(station_number__isnull=True))).exclude(pk=first.pk).update(time_exceptions='N')
本文链接:https://www.f2er.com/3151743.html

大家都在问