You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django模型计算航班出发到达时间差报str减法不支持错误如何解决

问题原因
  • 视图层直接从request.POST中获取的departure_time、arrival_time都是字符串类型,未做类型转换就传入模型实例,导致模型中执行减法运算时操作数都是字符串,触发类型错误。
  • 即便完成字符串到datetime.time类型的转换,Python原生的time类型本身不支持直接做减法运算,无法直接得到时间差值。
修复方案

步骤1:修改视图层,对时间参数做类型转换

先引入datetime模块,将POST提交的时间字符串转换为time类型,需要注意转换格式要和前端表单提交的时间格式保持一致,以下为示例(假设前端提交的时间格式为时:分,即%H:%M):

from datetime import datetime

def insert_flight(request):
    aircraft = Aircraft.objects.all()
    aerodrome = Aerodrome.objects.all()
    pilot = Pilot.objects.all()

    if request.method == 'POST':
        aircraft_id = request.POST.get('aircraft')
        from_aerodrome = request.POST.get('from_aerodrome')
        to_aerodrome = request.POST.get('to_aerodrome')
        # 转换时间字符串为time对象
        departure_time_str = request.POST.get('departure_time')
        arrival_time_str = request.POST.get('arrival_time')
        departure_time = datetime.strptime(departure_time_str, "%H:%M").time()
        arrival_time = datetime.strptime(arrival_time_str, "%H:%M").time()
        pilot = request.POST.get('pilot')
        instructor = request.POST.get('instructor') if request.POST.get('instructor') else None

        log_entry = LogEntry(
            aircraft_id=aircraft_id, 
            from_aerodrome_id=from_aerodrome, 
            to_aerodrome_id=to_aerodrome,
            departure_time=departure_time, 
            arrival_time=arrival_time, 
            pilot_id=pilot, 
            instructor_id=instructor
        )
        log_entry.save()

    context = {
        'aircraft': aircraft,
        'aerodrome': aerodrome,
        'pilot': pilot,
    }
    return render(request, 'flight/insert_flight.html', context)

步骤2:修改模型层的时间差计算逻辑

将两个time对象和日志的date字段拼接为datetime对象后再做减法,同时处理跨天飞行的场景,最后将时间差转为可读字符串存入eet字段:

from datetime import datetime, timedelta

class LogEntry(models.Model):
    aircraft = models.ForeignKey(Aircraft, on_delete=models.CASCADE)
    from_aerodrome = models.ForeignKey(
        Aerodrome, on_delete=models.PROTECT, related_name='from_aerodrome')
    to_aerodrome = models.ForeignKey(
        Aerodrome, on_delete=models.PROTECT, related_name='to_aerodrome')
    departure_time = models.TimeField()
    arrival_time = models.TimeField()
    pilot = models.ForeignKey(
        Pilot, on_delete=models.PROTECT, related_name='pilot')
    instructor = models.ForeignKey(
        Pilot, on_delete=models.PROTECT, related_name='instructor', blank=True, null=True)
    date = models.DateField(auto_now_add=True)
    remarks = models.CharField(max_length=1000, blank=True, null=True)
    eet = models.CharField(max_length=255)

    @property
    def get_eet(self):
        # 拼接为datetime对象
        dep_datetime = datetime.combine(self.date, self.departure_time)
        arr_datetime = datetime.combine(self.date, self.arrival_time)
        # 处理跨天场景
        if arr_datetime < dep_datetime:
            arr_datetime += timedelta(days=1)
        duration = arr_datetime - dep_datetime
        # 转换为 小时:分钟 格式的字符串
        total_seconds = duration.total_seconds()
        hours = int(total_seconds // 3600)
        minutes = int((total_seconds % 3600) // 60)
        return f"{hours:02d}:{minutes:02d}"

    def save(self, *args, **kwargs):
        self.eet = self.get_eet
        super(LogEntry, self).save(*args, **kwargs)

    class Meta:
        ordering = ('-arrival_time',)
        verbose_name_plural = 'Log Entries'
优化建议

可使用Django的ModelForm处理表单提交,Django会自动完成字段类型转换和校验,无需手动处理POST参数,减少类型错误概率。

内容的提问来源于stack exchange,提问作者Giorgio Scarso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 12:24:06