mercredi 13 août 2014

python - Django 1.4 : prefetch_related avec le gestionnaire de modèle personnalisé et order_by ? -Débordement de pile


This is a long shot question (doesn't seem like it is possible from the Django docs, but thought I'd ask just to see if anyone has any ideas). Note: I'm using Django 1.4.


I want to use a custom model manager on a prefetch_related() query. Then, on top of that, I want to order the prefetched results in a certain way.


To put it in simplified code, I have the following models (note: Participant model excluded from code because it is irrelevant):


class GoalParticipant(models.Model):
"""Many-to-many model between Goal and Participant models."""
participant = models.ForeignKey(
'Participant', related_name='goal_participants')
goal = models.ForeignKey('Goal', related_name='goal_participants')
active = models.BooleanField(default=True)

class Goal(models.Model):
name = models.CharField(max_length=50)
progress = models.IntegerField()
active = models.BooleanField(default=True)

class Milestone(models.Model):
name = models.CharField(max_length=50)
progress = models.IntegerField()
goal = models.ForeignKey('Goal', related_name='milestones')
active = models.BooleanField(default=True)

From here, my page controller gets a GoalParticipant Id value (called, say, pid). I want to display all of the goals and milestones for that ID.


So something like this would work normally:


GoalParticipant.objects.filter(participant=pid).select_related(
).prefetch_related('goal__milestones')

Here are the two wrinkles:


1: Custom Model Manager


All of my classes have custom model managers, like this:


  objects = ActiveManager()
all_objects = models.Manager()

The ActiveManager runs .filter(active=True) on the queryset. This is for convenience, so that I can easily just say .objects by default and have the active filter thrown in. Occasionally, though, I need to display all of the objects, not just active ones. So I tried this:


GoalParticipant.all_objects.filter(participant=pid).select_related(
).prefetch_related('goal__milestones')

This gives me all of the goal_participants and all of the goals, but still restricts to only active milestones. Is there a way to force prefetch_related to use the all_objects model manager?


2: Custom Ordering for Milestones


Users can actually order the goals / milestones by either name or progress in the UI, and the ordering should be consistent. For example, if the goals are ordered by progress, the milestones should also be ordered by progress. So, say I have a var called ordering with the correct ordering, I could do this:


GoalParticipant.objects.filter(participant=pid).select_related(
).order_by(ordering).prefetch_related('goal__milestones')

This orders the goals correctly, but there does not seem to be any way to force the milestones to order in the same way. Is there a way to do this?


Thanks in advance for your help and let me know if I can clarify anything.



This is a long shot question (doesn't seem like it is possible from the Django docs, but thought I'd ask just to see if anyone has any ideas). Note: I'm using Django 1.4.


I want to use a custom model manager on a prefetch_related() query. Then, on top of that, I want to order the prefetched results in a certain way.


To put it in simplified code, I have the following models (note: Participant model excluded from code because it is irrelevant):


class GoalParticipant(models.Model):
"""Many-to-many model between Goal and Participant models."""
participant = models.ForeignKey(
'Participant', related_name='goal_participants')
goal = models.ForeignKey('Goal', related_name='goal_participants')
active = models.BooleanField(default=True)

class Goal(models.Model):
name = models.CharField(max_length=50)
progress = models.IntegerField()
active = models.BooleanField(default=True)

class Milestone(models.Model):
name = models.CharField(max_length=50)
progress = models.IntegerField()
goal = models.ForeignKey('Goal', related_name='milestones')
active = models.BooleanField(default=True)

From here, my page controller gets a GoalParticipant Id value (called, say, pid). I want to display all of the goals and milestones for that ID.


So something like this would work normally:


GoalParticipant.objects.filter(participant=pid).select_related(
).prefetch_related('goal__milestones')

Here are the two wrinkles:


1: Custom Model Manager


All of my classes have custom model managers, like this:


  objects = ActiveManager()
all_objects = models.Manager()

The ActiveManager runs .filter(active=True) on the queryset. This is for convenience, so that I can easily just say .objects by default and have the active filter thrown in. Occasionally, though, I need to display all of the objects, not just active ones. So I tried this:


GoalParticipant.all_objects.filter(participant=pid).select_related(
).prefetch_related('goal__milestones')

This gives me all of the goal_participants and all of the goals, but still restricts to only active milestones. Is there a way to force prefetch_related to use the all_objects model manager?


2: Custom Ordering for Milestones


Users can actually order the goals / milestones by either name or progress in the UI, and the ordering should be consistent. For example, if the goals are ordered by progress, the milestones should also be ordered by progress. So, say I have a var called ordering with the correct ordering, I could do this:


GoalParticipant.objects.filter(participant=pid).select_related(
).order_by(ordering).prefetch_related('goal__milestones')

This orders the goals correctly, but there does not seem to be any way to force the milestones to order in the same way. Is there a way to do this?


Thanks in advance for your help and let me know if I can clarify anything.


0 commentaires:

Enregistrer un commentaire