2

I want to exclude non-active users from my project.

example 1:
  url:users/1/friends/ will show all friends of that user.

I want to show only active users in friend list.

example 2:
  url:users/1/friends/ will show all friends of that user.

if user with id 1 is not active i don't want to show any activity of him..like his friends..his profile...etc

example 3:
  url:users/1/challenge/  will show all friends of that user in post form.

i don't want to show non-active users in form.

is there any generic way to perform this. Because its a big project and I can't make filter everywhere.

Tables are like:

class User(models.Model):
  ......
  ......
  friends = models.ForeignKey(User)
Vini.g.fer
  • 11,639
  • 16
  • 61
  • 90

3 Answers3

6

You should use a custom Model Manager:

class ActiveUsersManager(models.Manager):
    use_for_related_fields = True

    def get_queryset(self):
        return super(ActiveUserManager, self).get_queryset().filter(is_active=True)


class User(models.Model):
    is_active = models.BooleanField(default=true)

    # first manager is the default and accessible through objects.
    active = ActiveUsersManager()
    all_users = models.Manager()

active_users = User.objects.all()    
all_users = User.all_users.all()
Yossi
  • 11,778
  • 2
  • 53
  • 66
  • thank ...but i am working on django rest framework and when a form is created by rest framework to post a request it automatically shows all entries of a ForeignkeyField. Means manager doesn't work at that time. – Pradeep Agnihotri May 20 '14 at 04:50
  • If I get it right, `use_for_related_fields = true` should be solving this. – Yossi May 20 '14 at 05:33
1

If you want to exclude non-active users from a queryset you can use the following filter:

YourModel.objects.exclude(friend__is_active=False)

# or 
YourModel.objects.filter(friend__is_active=True)

Where friend is a ForeignKeyField to a User model object in YourModel.

If you want a more general solution, you can use a ModelManager:

class ActiveUsersOnlyManager(models.Manager):
    def get_queryset(self):
        return super(ActiveUsersOnlyManager, self).get_queryset().filter(is_active=True)


class User(models.Model):
    is_active = models.BooleanField(default=true)
    friends = models.ForeignKey(User)
    # first manager is the default and accessible through objects.
    objects = ActiveUsersManager()
Maxime Lorant
  • 34,607
  • 19
  • 87
  • 97
  • i know that ....i want a generic solution so that i ll not need to filter the queryset everywhere , as you said above. – Pradeep Agnihotri May 19 '14 at 12:09
  • thank ...but i am working on django rest framework and when a form is created by rest framework to post a request it automatically shows all entries of a ForeignkeyField. Means manager doesn't work at that time. – Pradeep Agnihotri May 20 '14 at 04:58
0

You can use Creating a manager with QuerySet methods

can be used to create an instance of Manager with a copy of a custom QuerySet’s methods

class UserQuerySet(models.QuerySet):
    def active(self):
        return self.filter(is_active=True)

class User(models.Model):
    is_active = models.BooleanField(default=true)

    objects = UserQuerySet.as_manager()

And use it simply like this

User.objects.active()

For custom users (AbstractUser) you need this solution
It is based on this answer

from django.db.models import QuerySet
from django.contrib.auth.models import AbstractUser, UserManager


class UserQuerySetManager(UserManager):
    def __getattr__(self, attr, *args):
        try:
            return getattr(self.__class__, attr, *args)
        except AttributeError:
            # don't delegate internal methods to the queryset
            if attr.startswith('__') and attr.endswith('__'):
                raise
            return getattr(self.get_query_set(), attr, *args)

    def get_query_set(self):
        return self.model.QuerySet(self.model, using=self._db)


class User(AbstractUser):
    objects = UserQuerySetManager()


    class Meta:
        permissions = (
            ('view_all_managers', 'View All Managers'),
        )

    class QuerySet(QuerySet):
        def active(self):
            return self.filter(is_active=True)
Artem Bernatskyi
  • 4,185
  • 2
  • 26
  • 35