使用基于数据库项的动态过滤创建django-manager

时间:2012-11-16 11:35:08

标签: django django-models django-managers

标题有点粗糙,让我用更多细节来解释:

我有一个名为Identity的表,它是一个简单的表:

class Identity(models.model):

    identity_name = models.CharField(max_length=20, db_index=True) # name of the ID
    service_name = models.CharField(max_length=50)

数据库中的示例行将是具有identity_name='FacebookID'service_name='Facebook'的Facebook身份。

现在,要将其链接到用户,我有下表:

class UserIdentity(models.Model):

    user = models.ForeignKey('django.contrib.auth.models.User', db_index=True)
    identity_type = models.ForeignKey('Identity', db_index=True)
    value = models.CharField(maxlength=50) # the ID value

    objects = models.Manager()
    identities = IdentitesManager()

假设Bobdjango.contrib.auth.models.User的一个实例。我想通过Bob.identities.facebook访问其Facebook身份,其中facebookIdentitiesManager中动态生成的IdentitiesManager

现在你知道了上下文,这里有一个问题:如何从数据库中检索身份,在{{1}}中使用它们?

感谢阅读。

2 个答案:

答案 0 :(得分:0)

如果我理解了您的问题,您可以queryset中的模型获得Manager

class IdentitiesManager(models.Manager):
    def  some_func(self):
        qs = super(IdentitiesManager, self).get_query_set()

答案 1 :(得分:0)

最后,我发现了如何做到这一点。我创建了一个继承自dict的类,并根据dict中包含的数据创建了它的属性(带setattr)。类代码是:

class IdentityDictionary(dict):
    """ 
        Create a custom dict with the identities of a user.
        Identities are accessible via attributes or as normal dict's key/value.

    """

    def __init__(self, user, key='service_name'):

        identities = UserIdentity.objects.filter(user=user)
        dict_identities = dict([ (getattr(user_id.identity, key).replace(' ', '').lower(), user_id.identity) for user_id in identities ])

        super(IdentityDictionary, self).__init__(dict_identities)

        for id_name, id_value in dict_identities.items():
            setattr(self, id_name, id_value)

然后我将mixin添加到用户类:

class IdentitiesMixin(object):
""" 
    Mixin added to the user to retrieve identities 

"""
_identities_dict = {}
_is_identities_initialized = False

@property
def identities(self):
    if not self._is_identities_initialized :
        self._identities_dict = IdentityDictionary(self)
        self._is_identities_initialized = True

    return self._identities_dict

还有一点:自定义dict不是为了重用:如果dict是(希望,它不是类用例的问题),属性不会更新。