Question

The title is a little rough so let me explain it with more details:

I have a table called Identity which is a simple table like that:

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)

An example row in the database would be a Facebook identity with identity_name='FacebookID' and a service_name='Facebook'.

Now, to link that to a user, I have the following table:

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()

Let say Bob is a instance of the django.contrib.auth.models.User. I would like to access its Facebook identity with Bob.identities.facebook where facebook is dynamically generated in the IdentitiesManager.

Now you know the context, here is the question: how do I retrieve from the database the identities, to use them in the IdentitiesManager ?

Thanks for reading.

Was it helpful?

Solution 2

Finally, I found how to do that. I created a class inheriting from dict and made it create its attributes (with setattr) based on the data contained in the dict. The class code is :

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)

Then I made a mixin to add to the user class:

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

One more point: the custom dict is not intended for reusability : attributes are not updated if the dict is (hopefully, it is not a problem with the class use cases).

OTHER TIPS

If i have understood your question, you can get queryset for the model in the Manager as:

class IdentitiesManager(models.Manager):
    def  some_func(self):
        qs = super(IdentitiesManager, self).get_query_set()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top