如何编写包含Django ORM而没有循环引用的Python类(用于memcaching)?

时间:2021-05-19 03:49:51

My Django application contains the following two models:

我的Django应用程序包含以下两个模型:

# Start file person.py
class Person(models.Model):
    name = models.CharField(max_length=254,null=False, blank=False,)

    @property
    def things(self):
        return self.Thing_created_by.all()
# End file person.py

and

# Start file thing.py
from person import Person
class Thing(models.Model):
    name = models.CharField(max_length=254,null=False, blank=False,)
    created_by = models.ForeignKey(Person, related_name="Thing_created_by")
# End file thing.py

I want to write wrapper classes respectively named CachedPerson and CachedThing) that would be drop-in-replacements for these two classes. CachedPerson and CachedThing would act as a middleware to load instances of Person or Thing into memcached. If the instances were already loaded in memcached, they would be returned without hitting the Database of course.

我想编写分别命名为CachedPerson和CachedThing的包装类,这些类将是这两个类的替代品。 CachedPerson和CachedThing将充当中间件,将Person或Thing的实例加载到memcached中。如果实例已经在memcached中加载,那么它们将在没有命中数据库的情况下返回。

The idea is that invoking CachedPerson.__init__(self, pk=3) would retrieve Person.object.get(pk=3) from the database, serialize it and then store it (and its children CachedThings) in memcached with a corresponding unique key. CachedThing.__init__(self, pk=3) would work analogously. Basically I'm replicating copies of my ORM and storing them in memcached to increase performance. All reads/writes to the ORM will be handled by these wrapper classes.

想法是调用CachedPerson .__ init __(self,pk = 3)将从数据库中检索Person.object.get(pk = 3),对其进行序列化,然后将其(及其子CachedThings)存储在memcached中,并使用相应的唯一键。 CachedThing .__ init __(self,pk = 3)可以类似地工作。基本上我正在复制我的ORM副本并将它们存储在memcached中以提高性能。对ORM的所有读/写都将由这些包装类处理。

To illustrate this concept, here is what I want to be in memcached if Person #3 created Thing #4 and Thing #5:

为了说明这个概念,如果Person#3创建了Thing#4和Thing#5,那么这就是我想要在memcached中的内容:

{
    "Person_3": {
        "name": "Person #3",
        "things": [<CachedThing #4 Object>, <CachedThing #5 Object>],
    },
    "Thing_4": {
        "name": "Thing #4",
        "created_by": <CachedPerson #3 Object>,
    },
    "Thing_5": {
        "name": "Thing #5",
        "created_by": <CachedPerson #3 Object>,
    },
}

However, I'm struggling to write the CachedPerson.__init__() without getting caught with circular import references between CachedPerson and CachedThing. Calling Person.object.get(pk=3).things() returns Thing #4 and Thing #5. But to convert them to CachedThings, I need to call CachedThing.__init__(pk=4) and CachedThing.__init__(pk=5). That requires importing CachedThing, which would cause circular imports. So how can it be done?

但是,我正在努力编写CachedPerson .__ init __()而不会被CachedPerson和CachedThing之间的循环导入引用捕获。调用Person.object.get(pk = 3).things()返回Thing#4和Thing#5。但是要将它们转换为CachedThings,我需要调用CachedThing .__ init __(pk = 4)和CachedThing .__ init __(pk = 5)。这需要导入CachedThing,这会导致循环导入。那怎么办呢?

I wish Django had a middleware that would manage this complex ORM caching task for me. Alas it doesn't as far as I can tell. From what I have seen DjangoMemcached caches rendered HTML pages for me. That's not what I need. My entire Django app is a series of RESTful APIs. I'm not rendering any HTML. I need by Django Database Models held in the cache. Some of them are very complex and database intensive to access and modify.

我希望Django有一个中间件可以为我管理这个复杂的ORM缓存任务。唉,据我所知。从我所看到的DjangoMemcached缓存为我呈现的HTML页面。那不是我需要的。我的整个Django应用程序是一系列RESTful API。我没有渲染任何HTML。我需要缓存中保存的Django数据库模型。其中一些非常复杂且数据库密集,无法访问和修改。

1 个解决方案

#1


1  

You can import inside functions/methods:

您可以导入内部函数/方法:

class Person(models.Model):
    ...
    @property
    def things(self):
        from myapp.cachedthings import CachedThing
        ...

But I think that custom ModelManager is a better option for such task. Google for "django cache model manager" - there is a lot of tips and apps created for this purpose.

但我认为自定义ModelManager是这类任务的更好选择。 Google为“django缓存模型管理器” - 为此目的创建了许多提示和应用程序。

#1


1  

You can import inside functions/methods:

您可以导入内部函数/方法:

class Person(models.Model):
    ...
    @property
    def things(self):
        from myapp.cachedthings import CachedThing
        ...

But I think that custom ModelManager is a better option for such task. Google for "django cache model manager" - there is a lot of tips and apps created for this purpose.

但我认为自定义ModelManager是这类任务的更好选择。 Google为“django缓存模型管理器” - 为此目的创建了许多提示和应用程序。