Django如何将自定义对象指定为模型属性并在该对象中获取该模型实例?

2024-03-29 15:45:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我想从模型中分离一些逻辑并将其分组到属性中,就像Django处理模型管理器(object属性)一样。事实上,类似于ForeignKey但没有数据库表示

我有这样的想法:

class Remote(object):
    def __init(self, *args, **kwargs)
        self.post = ... # how to get to post instance?

    def synchronize(self):
       # this function requires Post object access
       print(self.post.name)

class Post(models.Model):
    name = models.CharField(max_length=100)
    remote = Remote()

...

for post in Post.objects.all():
    post.remote.synchronize()

问题

如何修改上述代码以访问Remote对象中的Post对象

附加问题

是否可以确定是否已从Post实例(post.remote...–如上所述)或Post类(Post.remote...)调用了Remote对象


Tags: to对象name模型selfsynchronize属性object
1条回答
网友
1楼 · 发布于 2024-03-29 15:45:54

您在这里想要的东西可以通过descriptors实现

为了让它工作,您需要在类中定义一个__get__方法,该方法要作为另一个类的属性进行访问

您的案例的一个简单示例如下所示:

class Remote:
    def __init__(self, post)
        self.post = post

    def synchronize(self):
       print(self.post.name)


class RemoteDescriptor:
    def __get__(self, obj):
        if not obj:
            return self
        remote = getattr(obj, '_remote', None)
        if not remote:
            remote = Remote(obj)
            obj._remote = remote
        return remote


class Post(models.Model):
    name = models.CharField(max_length=100)
    remote = RemoteDescriptor()

说明

在上面的代码中,每次调用Post模型的属性remote时,RemoteDescriptor__get__方法将被调用。obj的第一个检查是确保描述符是从其他对象调用的,而不是直接调用的。这里需要两个类Remote和RemoteDescriptor,以便您能够在描述符中添加自定义方法,这些方法可以使用dot访问(例如post.remote.calculate()

还请注意,在第一次调用和所有后续调用时,我将Remote的实例放在Post的dict中,对象将从那里返回

您还应该检查RealPython上描述符的great article

相关问题 更多 >