使用参数创建Django管理器 [英] Creating a django manager with a parameter

查看:65
本文介绍了使用参数创建Django管理器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下情况
我有一个经理类,可根据字段过滤查询集.问题是字段名称根据类而有所不同,但是它过滤的值来自同一位置(因此我认为我不需要几个管理器).这是我到目前为止所做的.

I have the following situation
I have a manager class that filters a queryset according to a field. The problem is that the field name is different according to the class but the value to which it filters comes from the same place (so i thought i don't need several managers). This is what i did so far.

class MyManager(models.Manager):
    def __init__(self, field_name):
        super(MyManager, self).__init__()
        self.field_name = field_name

    def get_queryset(self):
        # getting some value
        kwargs = { self.field_name: some_value }
        return super(MyManager, self).get_queryset().filter(**kwargs)

class A:
    # some datamembers

    @property
    def children(self):
        return MyUtils.prepare(self.b_set.all())

class B:
    objects = MyManager(field_name='my_field_name')
    a = models.ForeignKey(A, null=False, blank=False)

运行测试时,我从数据库中检索了一个B对象,并尝试读取 children 属性,但出现以下错误:

When i run tests i that retrieve from the DB a B object, and try to read the children property i get the following error:

self = <django.db.models.fields.related_descriptors.RelatedManager object at 0x7f384d199290>, instance = <A: A object>

    def __init__(self, instance):
>       super(RelatedManager, self).__init__()
E       TypeError: __init__() takes exactly 2 arguments (1 given)

我知道它的原因是构造函数参数,因为当我删除它(或给它一个默认值)时,所有测试都可以正常工作.
我该如何克服呢?这是实现此目标的正确方法吗?
技术资料:

I know its because of the constructor parameter because when i remove it (or give it a default value) all of the tests work.
How can i overcome this? Is this the right way of achieving this?
Tech stuff:

  1. Django 1.9.5
  2. 测试框架py.test 2.9.1

谢谢

推荐答案

另一种选择是动态生成Manager类,例如:

Another option would be to generate the Manager class dynamically, such as:

def manager_factory(custom_field):

    class MyManager(models.Manager):
        my_field = custom_field

        def get_queryset(self):
            # getting some value
            kwargs = {self.my_field: 'some-value'}
            return super(MyManager, self).get_queryset().filter(**kwargs)

    return MyManager()


class MyModel(models.Model):
    objects = manager_factory('custom_field')

通过这种方式,您可以将Manager与Model类分离.

This way you can decouple the Manager from the Model class.

这篇关于使用参数创建Django管理器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆