开发者

Writing a manager to filter query set results

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 k开发者_如何学Cnow 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.


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!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜