I am using an approach similar to T. Stone's answer on this question. However, I have added an abstract base class, so my models.py looks like this:
class CustomQuerySetManager(models.Manager):
"""A re-usable Manager to access a custom QuerySet"""
def __getattr__(self, attr, *args):
try:
return getattr(self.__class__, attr, *args)
except AttributeError:
return getattr(self.get_query_set(), attr, *args)
def get_query_set(self):
return self.model.QuerySet(self.model)
class MyModel(models.Model):
class Meta:
abstract = True
class QuerySet(QuerySet):
def user(self, pub, *args, **kwargs):
return self.filter(publisher=pub, *args, **kwargs)
...some more methods here
class Book(MyModel):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author, related_name='book_author')
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
objects=models.Manager()
obj=CustomQuerySetManager() #for testing purposes only, this will override objects later
This allows me to get all of the books for a given publisher like such:
p = Publisher.object.get(pk=1)
Book.obj.user(p).all()
I would like to extend this so I can define a custom query in the Book model then pass a Q object to the QuerySet class, so the query "publisher=pub" can be different for different models. I still want to be able to call this like Book.obj.user(p).all(). Somewhere in the Book model I need:
pubQ=Q(publisher=pub)
Where can I put this and how do I pass it to QuerySet defined in the Abstract Base Class, while keeping the code as DRY as possible?