split - django count specific rows in queryset -


class order(models.model):    name = models.charfield(max_length=100)    # other fields..    user = models.foreginkey(user)    old = models.booleanfield(default=false) 

i want display orders of specific user, want split them "old" , ones not.

so, in views.py:

orders = order.objects.filter(user=user) 

in template:

first table:

<table> {% order in orders %} {% if not order.old %}    <tr>      <td>... </td>     </tr> {% endif %} {% endfor %} </table> 

and table:

{% order in orders %} {% if order.old %}    <tr>      <td>...</td>    <tr> {% endif %} {% endfor %} 

this way have drawbacks, first, want count how many of orders "old", display number in template. can't, unless query. possible annotate(number_of_old=count('old'))? or have query?

so best?
1. 2 queries, 1 old=false, old=true, , pass 2 querysets template. , use |len filter on querysets
2. 1 query , split them somehow in python? less convenient have similar structures want split that.

and should call db .count() @ all?

edit:
if write model this:

class order(models.model):    name = models.charfield(max_length=100)    # other fields..    user = models.foreginkey(user)    old = models.booleanfield(default=false)    objects = custommanager() # custom manager   class customqueryset(models.queryset):     def no_old(self):         return self.filter(old=false)  class custommanager(models.manager):     def get_queryset(self):         return customqueryset(model=self.model, using=self._db) 

is template code produce 1 or 2 queries ?

{% if orders.no_old %} {% order orders.no_old %} ...  {% endfor %} {% endif %}  

you can't annotations, , there no need make .count() since have data in memory. between:

orders = order.objects.filter(user=user) old_orders = [o o in orders if o.old] new_orders = [o o in orders if not o.old]  #or  old_orders = order.objects.filter(user=user, old=true) new_orders = order.objects.filter(user=user, old=false) 

in specific scenario, don't think there performance difference. choose 2nd approach 2 queries.

a read tips problem: django database access optimization

update

about custom manager introduce. don't think doing correctly think want this:

class customqueryset(models.queryset):     def no_old(self):         return self.filter(old=false)  class order(models.model):    name = models.charfield(max_length=100)    # other fields..    user = models.foreginkey(user)    old = models.booleanfield(default=false)     #if have manager    #objects = custommanager.from_queryset(customqueryset)()    #if dont:    objects = customqueryset.as_manager() 

so having:

orders = order.objects.filter(user=user) 

if {% if orders.no_old %} query, because this new queryset instance has no cache..

about {% regroup %} tag

as mention, in order use it, need .order_by('old'), , if have order, can still use it, apply order after old, e.g. .order_by('old', 'another_field'). way use 1 query , save 1 iteration on list (because django split list iterating once), less readability in template.


Comments

Popular posts from this blog

Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12:test (default-test) on project.Error occurred in starting fork -

windows - Debug iNetMgr.exe unhandle exception System.Management.Automation.CmdletInvocationException -

configurationsection - activeMq-5.13.3 setup configurations for wildfly 10.0.0 -