【问题标题】:Two classes: one for the django model and one for representing the data outside of django两个类:一个用于 django 模型,一个用于表示 django 之外的数据
【发布时间】:2011-03-29 15:25:16
【问题描述】:

对于在特定 Django 应用程序的上下文中作为 Django 模型和在该特定应用程序之外作为非 Django 类存在的对象,是否有合理的模式来处理?

例如,假设我在 Django 应用程序博客中有一个 Post 模型。我希望能够在 Blog Django 应用程序之外以及可能在不同的 Django 应用程序中与代表这篇文章的类进行交互。

在过去,我刚刚创建了两个完全独立的类,它们的接口略有不同。 Django 模型包含从非 Django 版本创建或导出到非 Django 版本的 to 和 from 方法。但这对我来说完全错了。

编辑:我意识到我的语言和“访问”一词的使用令人困惑。我不是在问如何与 Django 应用程序对话,我是在问如何让 Django 模型类和非 Django 类以相同的接口表示相同的数据,我可以将 Django 模型对象导出到非 Django 类,所以我可以在另一个应用程序中使用它。 Errr,那可能也不清楚吧?

【问题讨论】:

  • 你还会使用数据库和 ORM 吗? (我们一直将 ORM 本身用于批处理作业。无需重复。)
  • 在定义模型的 django 应用程序的上下文中,我们将使用数据库、ORM 以及 django 为其提供的其余部分。但在特定的 django 应用程序之外,我希望能够以不依赖于任何数据库的方式表示该对象。
  • “我希望能够以不依赖于任何数据库的方式表示该对象” 为什么?这似乎是不必要的复杂性。这有什么用例?
  • 因为我有一个庞大的分布式系统来处理这些对象,而这些进程不能全部在连接到该数据库的 django 应用程序中运行;有时它们由连接到不同数据库的不同 django 应用程序处理。

标签: python django django-models


【解决方案1】:

如果我对您的理解正确,您有一些东西,您想在多个程序中将其表示为一个对象。更有趣的是,如果您的对象在 Django 程序的上下文中使用,您希望您的对象是 Django 模型,以便您可以将对象持久保存在数据库中,并完成所有其他整洁的工作Django 可以用模型做的事情。据推测,尽管您没有明确声明它,而不是仅枚举对象的属性,但您希望让对象实现而不管环境(Django 或其他环境)如何。

如果您是在 Java 或 C# 中实现此功能,我建议您这样做:

interface IFoo { ... }
class FooHelper { ... }
class app1.Foo extends Model implements IFoo { ... }
class app2.Foo implements IFoo { ... }

对于IFoo 中可用的每个方法,app1.Fooapp2.Foo 都需要通过委托给FooHelper 中的匹配方法来实现该方法。例如,bar 方法如下所示:

interface IFoo { 
    int bar(); 
}

class FooHelper { 
    int bar( object foo ) { ... } 
}

package app1;
class Foo extends Model implements IFoo {
    ...
    int bar() {
        return FooHelper.bar( this );
    }
}

package app2;
class Foo implements IFoo {
    ...
    int bar() {
        return FooHelper.bar( this );
    }
}

当然,FooHelper 必须足够聪明,才能根据传递的 Foo 类型做正确的事。

用 Python 解决这个问题应该更容易,因为 Python 是一种动态语言。

# Create a class decorator
def decorate_foo( fooclass ):

    def bar( self ):
        return 0

    fooclass.bar = bar

# Create a class to decorate
class Foo: pass

# Decorate the class
decorate_foo( Foo )

# Use the decorated class
f = Foo()
f.bar()

只需将所有功能放入 decorate_foo 函数中,然后让它在您需要调用添加的方法之一之前将该功能添加到类中。

【讨论】:

    【解决方案2】:

    您可以在正常服务器环境之外使用 Django 代码(就像测试用例一样)。如果您需要编写与您的 Django 模型一起使用的 Python 脚本,您可以像往常一样使用 ORM 访问/修改您的模型,您必须先使用一个简短的魔法咒语:

    from django.core.management import setup_environ
    from mysite import settings
    from myapp.models import MyModel
    
    setup_environ(settings)
    
    # Now do whatever you want with the ORM
    mystuff = MyModel.objects.all()
    

    我倾向于使用 management commands 来避免这种跑腿工作。

    如果您需要让多个 Django 应用程序访问这些数据,那很好 - 只需确保它们位于同一个 Django 项目中即可。

    如果您真的需要将它们放在单独的项目中,那么我可能会编写一个与 Django 视图交互的 API,以添加、获取、更新或删除我的模型 - 可能使用 REST API。你可以得到一些想法here

    【讨论】:

    • 我绝对不希望模型被用作它来自的 django 应用程序之外的模型。而且我在将数据传入和传出应用程序时没有问题。我遇到的问题是我正在编写两个看起来非常相似但它们具有不同 API 的类。有没有一种方法可以最小化每次我想要的东西时我必须编写的代码的数量和复杂性 1. 用 django 表示为数据库中的表和 2. 与数据库上下文之外的交互。
    【解决方案3】:

    我很难想象你所说的“访问 Django 应用程序之外的对象”是什么意思。外部应用程序将如何获取定义模型实例的数据?这两个应用程序是如何相关的——它们只是相同代码的不同区域,还是它们完全独立的进程通过 HTTP 之类的方式进行通信?

    如果它们是分开的,您可能希望为您的模型创建一个 RESTful API,然后外部应用程序可以通过 HTTP 访问该 API。 django-piston 项目使这变得简单。那是你追求的那种东西吗?

    【讨论】:

      猜你喜欢
      • 2011-01-16
      • 2016-06-15
      • 1970-01-01
      • 2014-05-15
      • 2010-10-25
      • 2021-02-11
      • 2019-11-27
      • 2013-08-09
      • 2021-10-01
      相关资源
      最近更新 更多