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

如何在Django中遍历Thermocouple模型创建TemperatureRecord数据表

问题背景

已实现Thermocouple模型用于管理热电偶,需要创建TemperatureRecord模型,为每个已存在的热电偶记录温度数据并存储到数据库。

现有数据

Thermocouple表数据

Idname
1thermocouple_1
2thermocouple_2
3thermocouple_3

期望的TemperatureRecord表结构

iddatetimeuserthermocouple_1thermocouple_2thermocouple_3
12024-03-0514:481温度值1温度值2温度值3
22024-03-0514:522温度值1温度值2温度值3
32024-03-0514:551温度值1温度值2温度值3
现有Thermocouple模型代码
class Thermocouple(models.Model):
    name = models.CharField(max_length=50, unique=True, help_text="Name of the thermocouple")

    def __str__(self):
        return f"{self.name}"

    class Meta:
        ordering = ['id']

    @classmethod
    def bulk_create_from_import(cls, data):
        cls.objects.bulk_create([cls(**item) for item in data])
尝试的无效代码

尝试在__init__方法中动态添加温度字段,但未生效:

class TemperatureRecord(models.Model):
    date = models.DateField()
    time = models.TimeField()
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    
    def __init__(self, *args, **kwargs):
        super(TemperatureRecord, self).__init__(*args, **kwargs)
        temperatures = Thermocouple.objects.all()
        for thermocouple in temperatures:
            field_name = thermocouple.name.lower().replace(" ", "_")  # 创建对应热电偶的字段名
            setattr(self, field_name, models.IntegerField(null=True, blank=True)) 
问题原因

在模型的__init__方法中动态添加字段是无效的,因为Django的模型字段是在类定义阶段注册到模型元数据中的,实例化时添加的字段不会被数据库识别,也无法生成对应的表结构。

解决方案

方案1:动态生成模型字段(适合固定数量的热电偶)

在TemperatureRecord类定义完成后,遍历已有的Thermocouple实例,动态为模型添加对应的温度字段。注意:后续新增热电偶需要重新执行迁移命令更新表结构。

from django.db import models
from django.contrib.auth.models import User
from .models import Thermocouple

class TemperatureRecord(models.Model):
    date = models.DateField()
    time = models.TimeField()
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return f"记录 {self.id} - {self.date} {self.time}"

# 动态添加每个热电偶对应的温度字段
for thermocouple in Thermocouple.objects.all():
    field_name = thermocouple.name.lower().replace(" ", "_")
    # 使用add_to_class方法为模型添加字段
    TemperatureRecord.add_to_class(
        field_name,
        models.IntegerField(null=True, blank=True, verbose_name=f"{thermocouple.name} 温度")
    )

注意事项

  1. 首次运行前需确保Thermocouple表已创建并存在数据,否则不会生成任何温度字段
  2. 新增热电偶后,需重新运行代码并执行python manage.py makemigrations和python manage.py migrate更新数据库
  3. 此方案适合热电偶数量固定或极少变化的场景

方案2:关联模型设计(推荐,支持动态增减热电偶)

如果热电偶数量会动态变化,宽表结构会导致频繁修改表结构,推荐使用一对多的关联模型,将每个热电偶的温度读数作为独立记录存储:

class TemperatureRecord(models.Model):
    date = models.DateField()
    time = models.TimeField()
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return f"记录 {self.id} - {self.date} {self.time}"

class TemperatureReading(models.Model):
    record = models.ForeignKey(TemperatureRecord, on_delete=models.CASCADE, related_name="readings")
    thermocouple = models.ForeignKey(Thermocouple, on_delete=models.CASCADE)
    temperature = models.IntegerField(null=True, blank=True)

    class Meta:
        unique_together = ('record', 'thermocouple')  # 确保同一记录中每个热电偶仅存一个读数

    def __str__(self):
        return f"{self.thermocouple.name}: {self.temperature}"

优势

  • 新增/删除热电偶无需修改表结构,直接操作Thermocouple模型即可
  • 数据结构更灵活,可轻松扩展温度单位、读数精度等字段
  • 查询时通过record.readings.all()即可获取该记录下所有热电偶的读数

内容的提问来源于stack exchange,提问作者Aashutosh Shrestha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 18:15:30