Django how to get 0 instead of null - django

I'm filtering a query set to get the number of visitors and pageviews but when there is no data it returns None.
How to get 0 instead of None when filtering a queryset when there is no data?
yesterday_visitors = queryset.filter(date__gte=yesterday, page=None).aggregate(Sum('visitors'))
yesterday_page_views = queryset.filter(date__gte=yesterday, page=None).aggregate(Sum('page_views')) ```

I've finally ended up doing it another way that is probably the easiest one, by just adding "or 0" at the end while use get __sum on "visitors" and "page_views" :
yesterday_visitors = queryset.filter(date__gte=yesterday, page=None).aggregate(Sum('visitors')).get('visitors__sum') or 0
yesterday_page_views = queryset.filter(date__gte=yesterday, page=None).aggregate(Sum('page_views')).get('page_views__sum') or 0

Related

Django Queryset GET (1 result) checking MAX value of one filed

Maybe the solution is to do it with Filter and then loop. But let's see if you guys can tell me a way to do it with GET
I have this query with GET as I need to be sure I get only one result
result = OtherModel.objects.get(months_from_the_avail__lte=self.obj.months_from_avail)
Months_from_avail is an Integer value.
Example
months_from_the_avail = 22
In the other model there's 3 lines.
A) months_from_the_avail = 0
B) months_from_the_avail = 7
C) months_from_the_avail = 13
So, when I query it returns all of them as all are less than equal the value 22 but I need to get the 13 as is the last range.
range 1 = 0-6
range 2 = 7-12
range 3 = 13 ++
Is there any way that I haven't thought to do it? Or should I change it to filter() and then loop on the results?
you can get the first() section from the query order_by months_from_the_avail
Remember that django query are lazy, it won't execute until the query if finished calling so you can still use filter:
result = OtherModel.objects.filter(months_from_the_avail__lte=self.obj.months_from_avail).order_by('-months_from_the_avail').first()
#order by descending get first object which is the largest, return None if query set empty
another suggestion from Abdul which i think it's faster and better is using latest()
OtherModel.objects.latest('-months_from_the_avail')

Select a row and column from a query in coldfusion 10

Can I select a certain row/column combination in coldfusion without doing a query of queries? For example:
Some Query:
ValueToFind | ValueToReturn
String 1 | false
String 2 | false
String 3 | true
Can I somehow do #SomeQuery["ValueToFind=String 3"][ValueToReturn]# = true without doing a query of queries ? I know there's code out there to get a certain row by id, but I'm not sure how or if I can do it when I need a string as the ID
If this can't be done, is there a short hand way to set up a coldfusion function so I can use something like FindValue(Query, "String 3") and not have to use ?
You can treat a query column as an array.
yourRow = ArrayFind(queryName['columnName'], "'the value you seek'");
If you get a zero, the value you seekis not there.
Edit starts here:
For values of other columns in that row, simply use that variable.
yourOtherValue = queryName.otherColumnName[yourRow];
A small modification to Dan's code, you can find the column value using the code below
yourVaue = SomeQuery["ValueToReturn"][ArrayFind(SomeQuery['ValueToFind'], "String 3")]

Get id of next object in Django model

I have a function that is passed in the id of an object in my class Image. I need the id of the next object in the model. Currently, I am doing it in the least efficient way possible as I need to get all the objects to do this. My current implementation is:
def get_next_id(curr_id):
result = []
Image_list = Image.objects.all()
total = Image.objects.all().count()
for i in range(len(Image_list)):
result.append(Image_list[i].id)
index_curr = result.index(curr_id)
if index_curr == total:
new_index = 0
else:
new_index = index_curr + 1
return Image_list[new_index]
I would be grateful if someone could provide a better way, or make this one more efficient. Thank you.
I would suggest something like this:
def get_next_id(curr_id):
try:
ret = Image.objects.filter(id__gt=curr_id).order_by("id")[0:1].get().id
except Image.DoesNotExist:
ret = Image.objects.aggregate(Min("id"))['id__min']
return ret
This does not take care of the special case where the table is empty, but then you should not have a valid curr_id in the first place if the table is empty. It also does not protect against passing nonsensical values as curr_id.
What this does is get first id which is greater than the current one. The [0:1] slice limits the data returned from the database to the first record: in effect the database is performing the slice rather than Python. If there is no id greater than the current one, then get the lowest one.
In response to your comment about how to do it in reverse:
def get_prev_id(curr_id):
try:
ret = Image.objects.filter(id__lt=curr_id).order_by("-id")[0:1].get().id
except Image.DoesNotExist:
ret = Image.objects.aggregate(Max("id"))['id__max']
return ret
The changes are:
Use id__lt, and order by -id.
Use Max rather than Min for the aggregate, and use the id__max key rather than id__min to get the value.

django queryset counts substrings in charField

One field in my model is a charField with the format substring1-substring2-substring3-substring4 and it can have this range of values:
"1-1-2-1"
"1-1-2-2"
"1-1-2-3"
"1-1-2-4"
"2-2-2-6"
"2-2-2-7"
"2-2-2-9"
"3-1-1-10"
"10-1-1-11"
"11-1-1-12"
"11-1-1-13"
For example I need to count the single number of occurrences for substring1.
In this case there are 5 unique occurrences (1,2,3,10,11).
"1-X-X-X"
"2-X-X-X"
"3-X-X-X"
"10-X-X-X"
"11-X-X-XX"
Sincerely I don't know where I can start from. I read the doc https://docs.djangoproject.com/en/1.5/ref/models/querysets/ but I didn't find a specific clue.
Thanks in advance.
results = MyModel.objects.all()
pos_id = 0
values_for_pos_id = [res.field_to_check.split('-')[pos_id] for res in results]
values_for_pos_id = set(values_for_pos_id)
How does this work:
first you fetch all your objects (results)
pos_id is your substring index (you have 4 substring, so it's in range 0 to 3)
you split each field_to_check (aka: where you store the substring combinations) on - (your separator) and fetch the correct substring for that object
you convert the list to a set (to have all the unique values)
Then a simple len(values_for_pos_id) will do the trick for you
NB: If you don't have pos_id or can't set it anywhere, you just need to loop like this:
for pos_id in range(4):
values_for_pos_id = set([res.field_to_check.split('-')[pos_id] for res in results])
# process your set results now
print len(values_for_pos_id)
Try something like this...
# Assumes your model name is NumberStrings and attribute numbers stores the string.
search_string = "1-1-2-1"
matched_number_strings = NumberStrings.objects.filter(numbers__contains=search_string)
num_of_occurrences = len(matches_found)
matched_ids = [match.id for match in matched_number_strings]
You could loop through these items (I guess they're strings), and add the value of each substring_n to a Set_n.
Since set values are unique, you would have a set, called Set_1, for example, that contains 1,2,3,10,11.
Make sense?

How to get the *total* number of results from a paginated `findBy` in Doctrine2?

I'm trying to see if there is a way to do pagination with Doctrine2 without writing custom DQL. I've found that the findBy() function returns the result set that I want, however I'm missing one piece of information to properly paginate on the UI, namely the total number of records that the result could have returned.
I'm really hoping that this is possible, since it's a "simple" one liner.
$transactions = \Icarus\Entity\ServicePlan\Transaction::getRepository()->findBy(array('user' => $userId, 'device' => $device), null, $transactionsPerPage, $currentPage);
Does anyone know how/if I can get this information from the findBy() function?
Short anwser, no. You're essentially running this query:
SELECT * FROM transaction WHERE user = $userId AND device = "$device" LIMIT $currentPage, $transactionPerPage;
By specifying a limit, the query is only going to return the amount of rows from your offset inside that limit. So if $transactionPerPage = 10, the total rows returned by that query will be 10.
Assuming the total count is somewhat static, I would suggest first running a count on the total matching documents on the first page request and caching that result ( or storing in sessions ), so you only need to grab the total count once.
edit: Example of count query, using just normal php sessions:
if ( !isset( $_SESSION['transactionCount'] ) )
{
$transactionCount = $em->createQuery('SELECT COUNT(*) FROM \Icarus\Entity\ServicePlan\Transaction WHERE user = ?1 AND device = ?2')
->setParameters( array( 1 => $userId, 2 => $device ) )
->getSingleScalarResult();
$_SESSION['transactionCount'] = $transactionCount;
}
edit2: If you really dont want to use DQL, you can run your .findBy() with out the offset and limit, and do a sizeof on the results:
$transactions = \Icarus\Entity\ServicePlan\Transaction::getRepository()->findBy(array('user' => $userId, 'device' => $device) );
$totalTransactions = sizeof( $transactions );
But the performance on this wont be as good, as you are actually fetching all the objects.
Did you try this ?
$queryBuilder->select('p.id, p.name')
->from('\Api\Project\Entity\Project', 'p')
->where('p.status = :status')
->setParameter('status', 1)
->orderBy('p.createdDate', 'asc')
->setFirstResult($page)
->setMaxResults($limit);