如何处理Django动态表单POST的多组epochs数据生成NMEA字符串?
问题描述
我正在编写Python函数,将Django动态表单提交的标准POST请求数据转换为指定格式的NMEA字符串。表单无静态元素,epochs为动态生成,所有目标字段均以epochs-NUMBER-开头。
目前我的函数仅能处理单组epochs-0-相关数据,需要实现循环逻辑,为每组epochs数据生成一行符合要求的NMEA格式字符串。
POST请求示例
csrfmiddlewaretoken=hJmSuP3O6GmtwBeJhfqb99LaCVOKxgngGNIEqoqhQQR7tQELUVGHeXRXxfnRE1Ah&base-TOTAL_FORMS=1&base-INITIAL_FORMS=0&base-MIN_NUM_FORMS=0&base-MAX_NUM_FORMS=1000&base-0-time=25.06.2024+13%3A36%3A00&base-0-show_differences=on&base-0-show_null=1&source=Manual&epochs-TOTAL_FORMS=3&epochs-INITIAL_FORMS=3&epochs-MIN_NUM_FORMS=0&epochs-MAX_NUM_FORMS=1000&unit_selector=m&unit_selector=m&unit_selector=m&unit_selector=m&epochs-0-target_name=250.01.G&epochs-0-easting=55555&epochs-0-northing=5555&epochs-0-height=555&epochs-0-azimuth=&epochs-0-zenithangle=&epochs-0-slope_dist=&epochs-1-target_name=170.01.G&epochs-1-easting=44646&epochs-1-northing=6554&epochs-1-height=544&epochs-1-azimuth=&epochs-1-zenithangle=&epochs-1-slope_dist=&epochs-2-target_name=150.01.G&epochs-2-easting=78979878&epochs-2-northing=4645&epochs-2-height=455&epochs-2-azimuth=&epochs-2-zenithangle=&epochs-2-slope_dist=
当前实现代码
def nmea_string(self, request, target_name): my_dict = {} keys = [] values = [] target_raw_string = ("PTER," + self.short_name + "_TRG," + target_name + "," + self.time.strftime("%Y-%m-%d %H:%M:%S") + "," + str(self.status_target)) for key, value in request.POST.items(): keys.append(key) values.append(value) for i in range(len(keys)): my_dict.update({keys[i]: values[i]}) for k, v in my_dict.items(): if k.startswith('epochs-0-'): if v == '': v = '-9999.999900' if k.startswith('epochs-0-target_name'): target_raw_string += "," + v else: target_raw_string += "," + v + ",0.000000" tg_checksum = self.get_checksum(target_raw_string) tg_nmea_string = "$" + target_raw_string + "*" + tg_checksum + "\n" nmea_string += tg_nmea_string return nmea_string
预期输出格式
$PTER,TS_TRG,250.01.G,2024-04-22 23:00:00,129,675666.252000,0.000000,252132.398000,0.000000,412.137000,0.000000,-9999.999900,0.000000,-9999.999900,0.000000,-9999.999900,0.000000*1F $PTER,TS_TRG,170.01.G,2024-04-22 23:00:00,129,675704.440000,0.000000,252162.055000,0.000000,412.341000,0.000000,-9999.999900,0.000000,-9999.999900,0.000000,-9999.999900,0.000000*1A
修改后的解决方案
要处理多组epochs数据,核心是先获取epochs-TOTAL_FORMS的值确定循环次数,然后遍历每个索引为每组单独构建NMEA行,同时优化原代码中冗余的字典构建逻辑:
def nmea_string(self, request, target_name): post_data = request.POST.dict() # 获取需要处理的epochs总组数 epochs_count = int(post_data.get('epochs-TOTAL_FORMS', 0)) nmea_lines = [] # 构建固定前缀部分 base_prefix = f"PTER,{self.short_name}_TRG,{target_name},{self.time.strftime('%Y-%m-%d %H:%M:%S')},{str(self.status_target)}" for epoch_idx in range(epochs_count): # 初始化当前epoch的原始字符串 raw_string = base_prefix # 遍历当前epoch的所有字段 for key, value in post_data.items(): if key.startswith(f'epochs-{epoch_idx}-'): # 处理空值 if not value: value = '-9999.999900' # target_name字段不需要追加0.000000 if key.endswith('target_name'): raw_string += f",{value}" else: raw_string += f",{value},0.000000" # 生成完整NMEA行 checksum = self.get_checksum(raw_string) nmea_line = f"${raw_string}*{checksum}\n" nmea_lines.append(nmea_line) # 合并所有行并返回 return ''.join(nmea_lines)
关键修改点
- 直接使用
request.POST.dict()转换POST数据,去掉原代码中冗余的列表转字典逻辑 - 通过
epochs-TOTAL_FORMS动态获取处理组数,实现循环遍历所有epochs - 为每个epoch单独构建NMEA字符串,解决原代码仅处理
epochs-0-的局限 - 用f-string简化字符串拼接,提升代码可读性
- 采用列表存储所有NMEA行后再合并,避免字符串累加的性能损耗
内容的提问来源于stack exchange,提问作者Oliver Bender
相关产品推荐
相关产品推荐

