I made a custom manager that has to randomize my query:
class RandomManager(models.Manager):
def randomize(self):
count = self.aggregate(count=Count('id'))['count']
random_index = random.randint(0, count - 1)
return self.all()[random_index]
When I use the method defined in my manager in the first place, it's works ok:
>>> PostPages.random_objects.randomize()
>>> <PostPages: post 3>
I need to randomize the already filtered query. When I tried to use the manager and the method in chain I got an error:
PostPages.random_objects.filter(image_gallary__isnull=False).randomize()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/home/i159/workspace/shivaroot/shivablog/<ipython-input-9-98f654c77896> in <module>()
----> 1 PostPages.random_objects.filter(image_gallary__isnull=False).randomize()
AttributeError: 'QuerySet' object has no attribute 'randomize'
Result of filtering is not an instance of model class, but it's django.db.models.query.QuerySet
, so that it does not have my manager and method, respectively.
Is there a way to use custom manager in chain query?
Custom managers. You can use a custom Manager in a particular model by extending the base Manager class and instantiating your custom Manager in your model. There are two reasons you might want to customize a Manager : to add extra Manager methods, and/or to modify the initial QuerySet the Manager returns.
It is used to get queryset of objects based on the properties it takes as arguments. If no argument is provided then it will return all the objects. In this example, we create a custom django manager by inheriting Manager class and overriding only the get_queryset method .
A Manager is a Django class that provides the interface between database query operations and a Django model. In other words, in a Django model, the manager is the interface that interacts with the database.
Model Manager is a web application that allows users to login to a Modeler server and perform common database and model management tasks on that Modeler Server. Executing tasks on the Modeler Server, instead of the Modeler Client, significantly improves performance of many operations.
This is how you chain custom methods on custom manager ie: Post.objects.by_author(user=request.user).published()
from django.db.models.query import QuerySet
class PostMixin(object):
def by_author(self, user):
return self.filter(user=user)
def published(self):
return self.filter(published__lte=datetime.now())
class PostQuerySet(QuerySet, PostMixin):
pass
class PostManager(models.Manager, PostMixin):
def get_query_set(self):
return PostQuerySet(self.model, using=self._db)
Link here : django-custom-model-manager-chaining
In Django 1.7 you have this out of the box . Check out QuerySet.as_manager
Just a code example using the new as_manager() method (see update information from @zzart.
class MyQuerySet(models.query.QuerySet):
def randomize(self):
count = self.aggregate(count=Count('id'))['count']
random_index = random.randint(0, count - 1)
return self.all()[random_index]
class MyModel(models.Model):
.....
.....
objects = MyQuerySet.as_manager()
.....
.....
And then you will be able to use something like this in your code:
MyModel.objects.filter(age__gt=16).randomize()
As you can see, the new as_manager() is really neat:)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With