两个类:一个用于Django模型,一个用于表示Django外的数据

4 投票
3 回答
809 浏览
提问于 2025-04-16 02:46

有没有一种合理的方法来处理一个对象,它在某个Django应用中是一个Django模型,而在这个应用之外又是一个非Django类?

举个例子,我在Django应用Blog中有一个Post模型。我希望能够在Blog这个Django应用之外,甚至在另一个Django应用中,与一个表示这个帖子(Post)的类进行交互。

以前我只是创建了两个完全不同的类,它们的接口稍微有点不同。Django模型里有一些方法,可以把非Django版本的数据转换成Django模型,或者把Django模型的数据导出到非Django版本。但我觉得这样做不太对劲。

补充说明:我意识到我用的语言和“访问”这个词可能让人困惑。我并不是在问怎么和Django应用沟通,而是在问怎么让一个Django模型类和一个非Django类表示相同的数据,并且有相同的接口,这样我就可以把Django模型对象导出到非Django类中,以便在另一个应用中使用。呃,这样说可能也不够清楚,对吧?

3 个回答

0

我有点搞不清楚你说的“在Django应用之外访问对象”是什么意思。外部应用是怎么获取定义模型实例的数据的呢?这两个应用是怎么关联的?它们是同一代码的不同部分,还是完全独立的进程,通过像HTTP这样的方式进行通信?

如果它们是独立的,你可能需要为你的模型创建一个RESTful API,这样外部应用就可以通过HTTP访问它。django-piston这个项目可以让这个过程变得简单。你是在寻找这样的东西吗?

2

你可以在正常的服务器环境之外使用Django代码(就像测试案例那样)。如果你需要写一些Python脚本来操作你的Django模型,你可以像平常一样使用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()

我通常会通过使用管理命令来避免这些繁琐的步骤。

如果你需要多个Django应用程序来访问这些数据,那也没问题——只要确保它们在同一个Django项目里就行。

如果你真的需要把它们放在不同的项目中,那我可能会写一个API,和Django的视图进行交互,以便添加、获取、更新或删除我的模型——可能会使用REST API。你可以在这里找到一些实现的思路。

2

如果我理解得没错,你有一个东西,想在多个程序中把它当作一个对象来使用。更有趣的是,如果这个对象是在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函数中,然后在你需要调用新增的方法之前,让它把这些功能添加到类里。

撰写回答