views:

128

answers:

2

I'm writing an user-driven app with several zones to it. I want to allow users to customise their messaging settings so they only get emails on the parts and actions they care about. I've drawn up the following Class:

class EmailSetting(models.Model):
    user = models.ForeignKey(User, related_name="%(class)s_related_user")
    key = models.CharField(max_length=50)
    value = models.BooleanField()

This is to be used by a method called get_users(key, default), which should return a list of users. For example, if I ask for a list of users that are subbed in on a key="new_post", default=False, I should get a list of Users where they have an EmailSetting with a value of True for that key. That's simple enough because I can just use the EmailSetting model.

If the default is True, things appear to be harder. I've never done anything more complicated than basic look-ups with Models, so I need a hand.

From a full list of Users, I need to remove ones with a False EmailSetting. Short of doing another query on EmailSetting looking for False entries and iteratively cutting them out of the first queryset, I can't see how to do this...

... But there must be another way because that stinks.

A: 

Well here's how I did it:

def get_users(key, default):
    if not default:
        return [es.user for es in EmailSetting.objects.filter(key = key, value = True)]
    return User.objects.exclude(pk__in = [es.user.pk for es in EmailSetting.objects.filter(key = key, value = False)])

Blisteringly simple when you think about it! Gotta love the Python syntax some times =)

Oli
A: 

I changed your related name on the user field, as I don't think you want to refer to an EmailSetting with "user" in the name.

def get_users(key, default):
    if default:
        return User.objects.exclude(emailsetting__key=key, emailsetting__value=False)
    else:
        return User.objects.filter(emailsetting__key=key, emailsetting__value=True)
Daniel
Could you post how you changed the EmailSetting class? I've removed the _user from the end of it and reset the SQL but I'm getting FieldError: Cannot resolve keyword 'emailsetting' into field. type errors.
Oli
You should just be able to remove it: "user = models.ForeignKey(User)".
Daniel