I have the following code:
class GroupDepartmentManager(models.Manager):
def get_query_set(self):
return super(GroupDepartmentManager, self).get_query_set().filter(group='1')
class Department(models.Model):
name = models.CharField(max_length=128)
group = models.ForeignKey(Group)
def __str__(self):
return self.name
objects = GroupDepartmentManager()
... and it works fine. Only thing is that I need to replace group='1'
with group=(the group specified by group = models.ForeignKey(Group))
. I am having quite a time trying to determine whether that foreign key needs to be passed into the class, or into the get_query_set function, or what. I know that you can accomplish this with group.department_set.filter(group=desired group)
, but I am writing this model for the admin site, so I need to use a variable and not a constant after the = sign.
Working with Filter Easily the most important method when working with Django models and the underlying QuerySets is the filter() method, which allows you to generate a QuerySet of objects that match a particular set of filtered parameters.
A QuerySet represents a collection of objects from your database. It can have zero, one or many filters. Filters narrow down the query results based on the given parameters. In SQL terms, a QuerySet equates to a SELECT statement, and a filter is a limiting clause such as WHERE or LIMIT .
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.
I have a hunch that replacing the default Manager
on objects
in this manner might not be good idea, especially if you're planning on using the admin site... Even if it helps you with your Employees, it won't help you at all when handling Departments. How about a second property providing a restricted view on Departments alongside the usual objects
? Or move the standard Manager
from objects
to _objects
and rename from_same_group
to objects
if you really prefer your original approach for your app.
class Department(models.Model):
name = models.CharField(max_length=128)
group = models.ForeignKey(Group)
def __str__(self):
return self.name
objects = models.Manager()
@property
def from_same_group(self):
return Department.objects.filter(group__exact=self.group)
Also, I understand you know how to set up the admin site to take advantage of the funny Manager
; if not (or if I misunderstood your question somehow), leave a comment, I'll try to follow up sometime soon.
EDIT: OK, to make this more clear: if you do absolutely insist on replacing objects
, you'd probably want to do this:
class Department(models.Model):
name = models.CharField(max_length=128)
group = models.ForeignKey(Group)
def __str__(self):
return self.name
_objects = models.Manager()
@property
def objects(self):
# note the _objects in the next line
return Department._objects.filter(group__exact=self.group)
You might want to reconsider the relationship between the groups and departments if you find that trying to create a custom manager is too complex. Managers excel at simplifying common queries, but flop at displaying complex relationships between models and instances of models.
However, I think this article about filtering model objects with a custom manager will point you in the right direction. The author proposes a technique to perform a function call that returns a customized manager class that has the filter parameters you specify saved in the class so they don't get passed to the instance. Do it!
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