#3587: filter() and order_by()
---------------------------------------+------------------------------------
   Reporter:  [EMAIL PROTECTED]  |                Owner:  adrian          
     Status:  new                      |            Component:  Database wrapper
    Version:  0.95                     |           Resolution:                  
   Keywords:                           |                Stage:  Unreviewed      
  Has_patch:  0                        |           Needs_docs:  0               
Needs_tests:  0                        |   Needs_better_patch:  0               
---------------------------------------+------------------------------------
Old description:

> I suspect that this should be multiple tickets, but here goes...
> 
> This is to document where I had problems getting filter() and order_by()
> to do what I want. I'm using MySQL.
> Excerpts from my model :
> class Cadet(models.Model):
>     sqn = models.ForeignKey(Squadron)
>     enrollment_date = models.DateField(help_text="YYYY-MM-DD")
>     date_of_birth = models.DateField(help_text="YYYY-MM-DD")
> 
> class Camp(models.Model):
>     name = models.CharField(maxlength=40)
>     min_training_level = models.PositiveIntegerField("Minimum training
> level", default=0)
>     min_age = models.FloatField("Minimum age", max_digits=3,
> decimal_places=1, default=0)
> 
> class Application(models.Model):
>     cadet = models.ForeignKey(Cadet, edit_inline=models.STACKED,
> num_extra_on_change=1, num_in_admin=1)
>     year = models.IntegerField(maxlength=4, core=True, help_text="4-digit
> year", validator_list=[year_validator])
>     camp = models.ForeignKey(Camp, core=True)
>     training_level = models.PositiveIntegerField("current training
> level")
> 
> The only places I can find where I couldn't get filtering to work are
> where I'm doing something that is probably too complex to do with SQL
> (although I'm no SQL expert).
> 
> Here's the function I ended up with after trying to get it going with
> filter() :
> def exception_age(request, year_filter):
>     """Lists cadets that might not be the right age for the course they
> applied for."""
>     this_june = date(int(year_filter), 6, 1)
>     this_sept = date(int(year_filter), 9, 1)
>     apps = list(Application.objects.filter(year=year_filter))
>     # filter out any that are definitely the right age
>     apps = [a for a in apps if (a.cadet.age_on(this_june) <
> float(a.camp.min_age)) or (a.cadet.ages_out() < this_sept)]
> 
> I don't have the filter() versions that I tried along the way, but it was
> based on comparing the application.cadet.date_of_birth field.
> 
> This one involves comparing the values in two tables :
> def exception_eligibility(request, year_filter):
>     """Lists cadets not in the right level for the course they applied
> for."""
>     apps = list(Application.objects.filter(year=year_filter))
>     # filter out any that are in the right level
>     apps = [a for a in apps if a.training_level <
> a.camp.min_training_level]
>     # Sort the list by squadron number
>     apps.sort(key=sqn_of_app);
>     return render_to_response('camps/exception_eligibility.html',
> {'object_list' : apps,})
> 
> and this one requires doing a calculation on the difference between two
> fields (cadet.date_of_birth and cadet.enrollment_date) :
> def exception_enrollment(request, year_filter):
>     """Lists cadets enrolled too young who've applied this year."""
>     apps = list(Application.objects.filter(year=year_filter))
>     # filter out any that joined old enough
>     cdts = [a.cadet for a in apps if a.cadet.age_at_enrollment() < 12]
>     # Sort the list by squadron number
>     cdts.sort(key=sqn_of_cdt);
>     return render_to_response('camps/exception_enrollment.html',
> {'object_list' : cdts,})
> 
> I do  have examples of where order_by doesn't work. Here's one :
> def wing(app):
>     return app.cadet.sqn.wing.name
> 
> def camp_csv(request, year_filter, object_id):
>     [...]
>     app_list = list(camp.application_set.filter(year=year_filter))
>     # Sort by wing
>     app_list.sort(key=wing)
> #    app_list =
> camp.application_set.filter(year=year_filter).order_by('camps_application__c
> adet.sqn.wing.name')
>     [...]
> 
> You can see where I've commented-out what I wanted to do. The commented-
> out version gives :
> Exception Type:         OperationalError
> Exception Value:        (1054, "Unknown column
> 'camps_application__cadet.sqn.wing.name' in 'order clause'")
> 
> This is following a series of foreign keys (application belongs to cadet,
> belongs to sqn, belongs to wing).

New description:

 I suspect that this should be multiple tickets, but here goes...
 
 This is to document where I had problems getting filter() and order_by()
 to do what I want. I'm using MySQL.
 Excerpts from my model :
 {{{
 #!python
 class Cadet(models.Model):
     sqn = models.ForeignKey(Squadron)
     enrollment_date = models.DateField(help_text="YYYY-MM-DD")
     date_of_birth = models.DateField(help_text="YYYY-MM-DD")
 
 class Camp(models.Model):
     name = models.CharField(maxlength=40)
     min_training_level = models.PositiveIntegerField("Minimum training
 level", default=0)
     min_age = models.FloatField("Minimum age", max_digits=3,
 decimal_places=1, default=0)
 
 class Application(models.Model):
     cadet = models.ForeignKey(Cadet, edit_inline=models.STACKED,
 num_extra_on_change=1, num_in_admin=1)
     year = models.IntegerField(maxlength=4, core=True, help_text="4-digit
 year", validator_list=[year_validator])
     camp = models.ForeignKey(Camp, core=True)
     training_level = models.PositiveIntegerField("current training level")
 }}}
 
 The only places I can find where I couldn't get filtering to work are
 where I'm doing something that is probably too complex to do with SQL
 (although I'm no SQL expert).
 
 Here's the function I ended up with after trying to get it going with
 filter() :
 
 {{{
 #!python
 
 def exception_age(request, year_filter):
     """Lists cadets that might not be the right age for the course they
 applied for."""
     this_june = date(int(year_filter), 6, 1)
     this_sept = date(int(year_filter), 9, 1)
     apps = list(Application.objects.filter(year=year_filter))
     # filter out any that are definitely the right age
     apps = [a for a in apps if (a.cadet.age_on(this_june) <
 float(a.camp.min_age)) or (a.cadet.ages_out() < this_sept)]
 }}}
 
 I don't have the filter() versions that I tried along the way, but it was
 based on comparing the application.cadet.date_of_birth field.
 
 This one involves comparing the values in two tables :
 {{{
 #!python
 
 def exception_eligibility(request, year_filter):
     """Lists cadets not in the right level for the course they applied
 for."""
     apps = list(Application.objects.filter(year=year_filter))
     # filter out any that are in the right level
     apps = [a for a in apps if a.training_level <
 a.camp.min_training_level]
     # Sort the list by squadron number
     apps.sort(key=sqn_of_app);
     return render_to_response('camps/exception_eligibility.html',
 {'object_list' : apps,})
 }}}
 
 and this one requires doing a calculation on the difference between two
 fields (cadet.date_of_birth and cadet.enrollment_date) :
 
 {{{
 #!python
 
 def exception_enrollment(request, year_filter):
     """Lists cadets enrolled too young who've applied this year."""
     apps = list(Application.objects.filter(year=year_filter))
     # filter out any that joined old enough
     cdts = [a.cadet for a in apps if a.cadet.age_at_enrollment() < 12]
     # Sort the list by squadron number
     cdts.sort(key=sqn_of_cdt);
     return render_to_response('camps/exception_enrollment.html',
 {'object_list' : cdts,})
 }}}
 
 I do  have examples of where order_by doesn't work. Here's one :
 
 {{{
 #!python
 
 def wing(app):
     return app.cadet.sqn.wing.name
 
 def camp_csv(request, year_filter, object_id):
     [...]
     app_list = list(camp.application_set.filter(year=year_filter))
     # Sort by wing
     app_list.sort(key=wing)
 #    app_list =
 camp.application_set.filter(year=year_filter).order_by('camps_application__c
 adet.sqn.wing.name')
     [...]
 }}}
 
 You can see where I've commented-out what I wanted to do. The commented-
 out version gives :
 {{{
 Exception Type:         OperationalError
 Exception Value:        (1054, "Unknown column
 'camps_application__cadet.sqn.wing.name' in 'order clause'")
 }}}
 
 This is following a series of foreign keys (application belongs to cadet,
 belongs to sqn, belongs to wing).

Comment (by mtredinnick):

 Fixed formatting in summary.

-- 
Ticket URL: <http://code.djangoproject.com/ticket/3587#comment:6>
Django Code <http://code.djangoproject.com/>
The web framework for perfectionists with deadlines
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to