首页 > 解决方案 > 将基于 Python 实例的程序转换为 Django 数据库

问题描述

我的 Python 知识主要是后端、非 GUI/非 Web 编程。我有一个模拟燃料存储和传输系统的程序。主要程序使用阀门、泵等实例来跟踪系统参数(数据库可能更有意义,但当时用于物理建模的类更有意义)。

以下是 Valve 类的示例:

class Valve:
def __init__(self, name="", sys_flow_in=0.0, sys_flow_out=0.0, drop=0.0, position=0, flow_coeff=0.0, press_in=0.0):
    self.name = name
    self.__position = int(position)  # Truncate float values for ease of calculations
    self.Cv = float(flow_coeff)
    self.flow_in = float(sys_flow_in)
    self.deltaP = float(drop)
    self.flow_out = float(sys_flow_out)
    self.press_out = 0.0
    self.press_in = press_in

def calc_coeff(self, diameter):
    self.Cv = 15 * math.pow(diameter, 2)

def press_drop(self, flow_out, spec_grav=1.0):
    try:
        x = (flow_out / self.Cv)
        self.deltaP = math.pow(x, 2) * spec_grav
    except ZeroDivisionError:
        return "The valve coefficient must be > 0."

def valve_flow_out(self, flow_coeff, press_drop, spec_grav=1.0):
    try:
        if flow_coeff <= 0 or press_drop <= 0:
            raise ValueError("Input values must be > 0.")
        else:
            x = spec_grav / press_drop
            self.flow_out = flow_coeff / math.sqrt(x)
            return self.flow_out
    except ValueError:
        raise  # Re-raise error for testing

def get_press_out(self, press_in):
    if press_in:
        self.press_in = press_in  # In case the valve initialization didn't include it, or the value has changed
    self.press_drop(self.flow_out)
    self.press_out = self.press_in - self.deltaP

@property
def position(self):
    return self.__position

@position.setter
def position(self, new_position):
    try:
        if type(new_position) != int:
            raise TypeError("Integer values only.")
        else:
            self.__position = new_position
    except TypeError:
        raise  # Re-raise for testing

def open(self):
    self.__position = 100
    self.flow_out = self.flow_in
    self.press_out = self.press_in

def close(self):
    self.__position = 0
    self.flow_out = 0
    self.press_out = 0
    self.deltaP = 0

一个实例如下所示:

gate1 = valve.Gate("Gate valve 1", sys_flow_in=tank1.flow_out, press_in=tank1.static_tank_press)
gate1.calc_coeff(16)

我已将其转换为与 Kivy 一起使用,以提供简化的人机界面(只需在原理图文件中添加按钮),如下所示:在此处输入图像描述

我想编写一个 Django 版本来展示如何以多种方式使用相同的后端模型。问题是,由于我只完成了几个 Django 教程,我不确定 Django 是否是最好的工具。大多数教程专注于博客、新闻文章等,而不是类似于 Kivy 的界面。即使查看各种由 Django 提供支持的网站也显示出类似的概念,而不是任何类似于图形 HMI 的东西。

我能够将原理图作为静态文件放入我的 Django 代码中并向其中添加 HTML 按钮,所以我想我只需要弄清楚如何将按钮绑定到数据库。

我的问题是:Django 是最好的方法吗?我选择了 Django,因为它是 Python Web 开发的“黄金标准”,但怀疑它可能是错误的工具。

其次,是否有一种简单的方法,或者至少是一种方法,可以将类/实例转换为数据库项?我怀疑我将不得不从头开始重写代码以使其与数据库一起使用,但如果我不必做很多额外的工作,那就太好了。

标签: pythondjangokivy

解决方案


问题2

从第二个问题开始,在 Django 中将类和实例转换为数据库项非常简单。Django 有Models,它只是一个类,但它(通常)映射到数据库表,并且该类的实例映射到表中的一行。现有 Python 类到 Django 模型的一般过程是让类继承django.db.models.Model并将所有实例变量更改为模型字段,这些字段对应于数据库中模型表中的列。

下面是将纯 Python 类转换为 Django 模型的简单示例:

class Valve:
    def __init__(self, name="", flow_coeff=0.0):
        self.name = name
        self.Cv = float(flow_coeff)

    def calc_coeff(self, diameter):
        self.Cv = 15 * math.pow(diameter, 2)

变成:

from django.db import models

class Valve(models.Model):
    name = models.TextField()
    Cv = models.FloatField()

    def calc_coeff(self, diameter):
        self.Cv = 15 * math.pow(diameter, 2)
        self.save()

所以 Django 模型仍然可以有方法,并且两个版本的Valve类的构造函数是相同的,除了必须使用saveorcreate才能将 Django 模型版本保存到数据库中。

Django 还支持许多不同的数据库管理系统,默认使用 SQLite(我一般使用 PostgreSQL)。有关更多信息,请参阅https://docs.djangoproject.com/en/2.1/ref/settings/#databases

问题 1

关于 Django 是否适合这项工作:虽然这主要是一个基于意见的问题,但我相信 Django 适合这个问题。虽然大多数教程都侧重于博客和类似类型的网站,但我认为这只是因为这些示例适用范围广泛且易于理解(部分原因是缺乏创造力)。但是 Django 真的可以用来做任何事情。我用它在不同领域创建了许多不同的项目。一般来说,我将它用于数据库管理和作为 API,很少使用它提供的前端模板。


推荐阅读