【发布时间】:2020-04-18 05:30:12
【问题描述】:
由于这些天我有一些空闲时间,我决定学习一门新语言会很好。所以我选择了 python,因为它很受欢迎,而且我对 Django 很感兴趣。
几个小时后,尽管所有与语法相关的困难都源于一种新语言,但我还是设法进行了简单的后端逻辑设计(我的“应用程序”应该做什么)。现在下一步是将我的代码介绍给 Django,以最终以某种方式使该逻辑“真实”,并在此过程中学习一些 HTML、CSS。
在学习了 Django 的官方教程后,我觉得我学到了足够的东西来开始我的项目。
在我开始谈论 Django 的 ORM 之前,我想说的是,根据我在教程中看到和学到的内容,我非常喜欢 Django 的所有与 Web 相关的实用程序(视图、路径、模板)。至少目前看来,它们真的很容易学习和使用。
现在关于 ORM。
首先,我觉得有必要澄清一下,这是我这辈子使用的第二个ORM;我在其中一门课程中使用的第一个是 Java 的 JPA。
根据我使用 JPA 所学到的知识,我觉得 ORM 的主要目标之一是尽量不让我修改我已经编写的所有代码。这样一来,应用程序的开发就会很容易:
- st - 设计后端代码(案例用途、应用模型:类、对象、函数)。
- nd - 将该模型映射到关系模型,以便可以将其保存在数据库中。
- rd - 创建视图和所有前端的东西。
我遇到 Django 的 ORM 的第一个问题是没有 OneToMany 关系,所以如果在我的起始代码中我有:
class Question:
pass
class Exam:
__init__(self, questions):
self.questions = questions # list of questions
我不得不把它改成:
class Question:
exam = models.ForeignKey('Exam', on_delete=models.CASACADE, related_name='questions', ...)
class Exam:
pass
也许我不是很了解 Django 的“模型”,毕竟我只是一个新手。但我觉得这很可怕。如果我的“考试”类有依赖于使用这样的问题列表来完成工作的方法怎么办。我已经看到我可以使用an_exam.questions.all() 访问它,但我觉得这很糟糕,因为例如:
至少我的 IDE (PyCharm) 无法识别这些属性;我猜它们是在运行时定义的。这可能会导致运行时错误,以防我的类中使用了许多这些属性并且我弄乱了它们的名称。
再加上这样一个事实,即我可以在单独的文件中拥有我的课程(考试)和定义 ForeignKey(问题)的课程。所以我不能轻易知道我的班级有什么属性(更多错误)。
最后,我猜
an_exam.questions.all()返回与给定考试相关的所有问题,这些问题保存在数据库中。那些还没有的呢?
我遇到的另一个问题是我不应该重写__init__ 方法。这将使我改变我的类初始化的所有事件。当然,我可以绕过它,正如我在互联网上的某个地方看到的那样,定义一个 class_method 以便an_exam = Exam.new_exam();但为什么 Django 会让我这样做呢?
合并这两个问题:如果要初始化的类需要一个通过 OneToMany 关系与之相关的元素列表呢?以“考试”为例,我不仅会求助于创建初始化方法的阴暗想法,而且我还必须创建几个额外的设置方法,这些方法利用自动生成的“问题”属性(以及其他属性,如果存在)正确设置属性:
class Question:
exam = models.ForeignKey('Exam', on_delete=models.CASACADE, related_name='questions', ...)
class Exam:
@classmethod
def new_exam(cls, questions):
exam = Exam()
exam.set_questions(questions)
return exam
def set_questions(questions):
for q in questions:
q.exam = self
q.save()
# something like this
最后我想说我知道我是 Django 和 python 本身的新手。这就是为什么我确定我所说的一切以及更多内容一定是错误的;我这样做的目的是有人会指出我的错误。
我觉得我误解了 Django 模型的真正含义。我没有多想它们,我认为它们指的是我实际的应用程序逻辑/后端设计模型:职责是如何分配的,要满足的要求以及背后的逻辑。
我期待有人能照亮我走出这种压倒性和令人失望的感觉的道路。感谢您阅读到最后:)
【问题讨论】:
-
关于 PyCharm 没有拾取模型之间自动生成的反向关系的第一个问题。这是专业版中提供的东西,但社区版中没有
-
这很酷。但是,我仍然觉得在我的代码中使用它们并围绕它们重构我的代码有点错误。
-
但是反过来呢?如果您在模型上定义了“一对多”字段,那么您将在相关模型上隐式创建外键
-
Django 的设计理念是大多数数据输入都是通过用户输入完成的。您创建
Exam类的实例并将question关系的成员传递给它的示例具有 Django 范例 - docs.djangoproject.com/en/3.0/topics/forms/modelforms/… -
如果您来自 Java,最好不要过多回顾 Java 中的工作方式,而是使用 Python,这一定会让您感到沮丧。例如,getter 和 setter 是另一个巨大的分歧点,以及私有和公共属性限定符。话虽如此,欢迎来到????!