Django Redis 连接后端或如何实现一个

5 投票
1 回答
1730 浏览
提问于 2025-04-16 09:07

有没有什么插件或者第三方工具可以在Django中管理Redis连接,这样在view.py里就不用每次请求都明确连接Redis了?

如果没有,你会怎么开始实现一个呢?是做一个新的插件?还是新的后端?或者是新的Django中间件?

谢谢。

1 个回答

5

我觉得现在非关系型数据库的一个新标准是 django-nonrel。我不太确定django-nonrel是否已经可以用于生产环境,也不知道它是否支持redis,但他们有一个关于 编写自定义无关系数据库后端 的指南。

可惜的是,我觉得在标准的django上为redis写支持并不像写一个 DatabaseBackend 那么简单。因为django的模型机制和工作流程中有很多地方是默认假设你在用一个ACID数据库的。比如 syncdb 怎么办?还有 Querysets 呢?

不过,你可以尝试用 models.Manager 和对你的模型进行很多调整来写一个简单的解决方案。例如:

# helper   
def fill_model_instance(instance, values):
    """ Fills an model instance with the values from dict values """                                    
    attributes = filter(lambda x: not x.startswith('_'), instance.__dict__.keys())

    for a in attributes:
        try:
            setattr(instance, a, values[a.upper()])
            del values[a.upper()]
        except:
            pass

    for v in values.keys():
        setattr(instance, v, values[v])

    return instance




class AuthorManager( models.Manager ):

    # You may try to use the default methods.
    # But should be freaking hard...
    def get_query_set(self):
        raise NotImplementedError("Maybe you can write a Non relational Queryset()! ")

    def latest(self, *args, **kwargs):
        # redis Latest query
        pass

    def filter(self, *args, **kwargs):
       # redis filter query
       pass

    # Custom methods that you may use, instead of rewriting
    # the defaults ones.
    def open_connection(self):
        # Open a redis connection
        pass

    def search_author( self, *args, **kwargs ):
        self.open_connection()

        # Write your query. I don't know how this shiny non-sql works.
        # Assumes it returns a dict for every matched author.
        authors_list = [{'name': 'Leibniz',   'email': 'iinventedcalculus@gmail.com'},
                         'name': 'Kurt Godel','email': 'self.consistent.error@gmail.com'}]

        return [fill_instance(Author(), author) for author in authors_list]



class Author( models.Model ):
    name      = models.CharField( max_length = 255 )
    email     = models.EmailField( max_length = 255 )

     def save(self):
         raise NotImplementedError("TODO: write a redis save")

     def delete(self):
         raise NotImplementedError(""TODO: write a delete save")

     class Meta:
          managed = False

请注意,我只是简单勾勒了一下如何调整django模型。我并没有测试和运行这段代码。我建议你先去了解一下django-nonrel。

撰写回答