Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django custom manager with ManyToManyField

I have a model with a ManyToManyField with a through model in which there is a boolean field that I would like to filter upon.

from simulations.models import *
class DispatcherManager(models.Manager):
    use_for_related_fields = True

    def completed(self):
        original = super(DispatcherManager,self).get_query_set()
        return original.filter(dispatchedsimulation__status=True)
    def queued(self):
        original = super(DispatcherManager,self).get_query_set()
        return original.filter(dispatchedsimulation__status=False)

class Dispatcher(models.Model):
    name = models.CharField(max_length=64)
    simulations = models.ManyToManyField('simulations.Simulation',
            through='DispatchedSimulation')
    objects = DispatcherManager()

class DispatchedSimulation(models.Model):

    dispatcher = models.ForeignKey('Dispatcher')
    simulation = models.ForeignKey('simulations.Simulation')
    status = models.BooleanField()

I thought that the use_for_related_fields variable would allow me to filter the m2m results as on a dispatcher d like so: d.simulations.completed() or d.simulations.queued() but these do not appear to work as I had expected. Am I misunderstanding how the use_for_related_fields works, or am I doing something wrong?

like image 303
Bryan Ward Avatar asked Jan 09 '10 00:01

Bryan Ward


1 Answers

From the docs on Using managers for related object access:

you can force Django to use the same class as the default manager for your model by setting the use_for_related_fields attribute on the manager class.

Meaning, in your case, you can force d.simulation to use the normal SimulationManager (and not DispatcherManager - DispatcherManager will be used for the opposite direction of the link. For example, Simulation.objects.get(id=1).dispatcher_set.completed).

I think the simplest way to achieve what you want is to define a get_completed_simulations and a get_queued_simulations methods in DispatcherManager. So the usage would be d.get_completed_simulations().

like image 127
Ofri Raviv Avatar answered Oct 18 '22 14:10

Ofri Raviv