sort by count in json - python

I'm using tastypie to create json from my django models however I'm running into a problem that I think should have a simple fix.
I have an object Blogs wich has Comment object children. I want to be able to do something like this with my json:
/api/v1/blogs/?order_by=comment_count
But I can't figure out how to sort on a field that's not part of the original comment/ blog model. I create comment_count myself in a dehydrate method that just takes the array of comments and returns comments.count()
Any help would be much appreciated - I can't seem to find any explanation.

If I understood correctly this should help:
Blog.objects.annotate(comment_count=Count('comments')).order_by('comment_count')

You might be able to do it with extra like something like:
Blog.objects.extra(
select={
'entry_count': 'SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id'
},
order_by = ['-entry_count'],
)
I haven't tested this, but it should work. The caveat is it will only work with a relational database.

Related

Django: SELECT JsonField AS new_name?

I have a table, in which some attributes are columns, and some are implemented as a postgres JsonField.
For the columns, I can write eg
Product.objects.values(brand=F('brand_name'))
for implement a SELECT brand_name AS brand query.
I need to do something similar for a JsonField, eg
Product.objects.values(color=F('jsonproperties__color'))
However, the F expressions do not work correctly with JsonFields, and there doesn't seem to be a fix coming anytime soon.
How could I work around this?
Perhaps a simple list comprehension will do what you want:
[{"color": p["jsonproperties"]["color"]} for p in Product.objects.values("color")]

How do I order my objects in a random way?

I'm using Django with Python 3.7 and PostGres 9.5. I use the following to get all my objects and iterate over them ...
article_set = Article.objects.all()
for article in article_set:
Is there a way to modify my existing query or possibly the loop so that the objects are returned in a random order each time? I would prefer not to make a second query if at all possible.
As is explained in the documentation you can use order_by('?') as follows:
article_set = Article.objects.order_by('?')
Make a loop like this
article_set = Article.objects.all()
for article in random.shuffle(article_set):
print(article)
I'm not too familiar with Django, and correct me if I'm wrong but I'd assume that:
Article.objects.all()
#Roughly equates to:
"SELECT * from articles"
So I believe you should be able to do:
Article.objects.all().order_by('RANDOM()')
#Thus producing this SQL statement:
"SELECT * from articles ORDER BY RANDOM()"
Which should mix up your output.
Otherwise, I'd say go with the random.shuffle approach.
from random import shuffle
article_set = Article.objects.all()
for article in shuffle(article_set):
#do work
Let me know if the order_by worked and I can edit accordingly. Like I said I'm not too familiar with Django so this is untested but in theory should work. Thanks!

Programming error with order by and distinct on Django with PostgreSQL

There are a lot of similar posts but none that hit exactly at what I am trying to get to. I get that a distinct has to use the same fields as order_by, which is fine.
So I have the following query:
q = MyModel.objects.order_by('field1', 'field2', '-tstamp').distinct('field1', 'field2')
Ultimately I am trying to find the latest entry in the table for all combinations of field1 and field2. The order_by does what I think it should, and that's great. But when I do the distinct I get the following error.
ProgrammingError: SELECT DISTINCT ON expressions must match initial ORDER BY expressions
Ultimately this seems like a SQL problem (not a Django one). However looking at the django docs for distinct, it shows what can and can't work. It does say that
q = MyModel.objects.order_by('field1', 'field2', '-tstamp').distinct('field1')
will work (...and it does). But I don't understand that when I add on field2 in the same order as done in the order_by I still get the same result. Any help would be greatly appreciated
EDIT: I also notice that if I do
q = MyModel.objects.order_by('field1', 'field2', '-tstamp').distinct('field1', 'field2', 'tstamp') # with or without the - in the order_by
It still raises the same error, though the docs suggest this should work just fine
Was able to get the query to run properly by using pk's in the order_by()
q = MyModel.objects.order_by('field1__pk', 'field2__pk', '-tstamp').distinct('field1__pk', 'field2__pk')
Apparently when they are not ordinary types the orderby doesn't play super nice. However using the pk's of the objects seems to work
Test this one :
q = MyModel.objects.order_by('field1__id', 'field2__id', '-tstamp').distinct('field1__id', 'field2__id')

Mongoengine... How can I compare two fields?

For example..
class Example(Document):
up = IntField()
down = IntField()
and.. I want to retrieve documents whose up field is greater or equal to down.
But.. this is issue.
My wrong query code would be..
Example.objects(up__gte=down)
How can I use a field that resides in mongodb not python code as a queryset value?
Simple answer: not possible. Something like WHERE A = B in SQL is not doable in an efficient way in MongoDB (apart from using the $where clause which should be avoided).
this may be what you wanted::
db.myCollection.find( { $where: "this.credits == this.debits" } );
have a look at: http://docs.mongodb.org/manual/reference/operator/query/where/
but I donot know how to use it in mongoengine.

Really long query

How do u do long query? Is there way to optimize it?
I would do complicated and long query:
all_accepted_parts = acceptedFragment.objects.filter(fragmentID = fragment.objects.filter(categories = fragmentCategory.objects.filter(id=1)))
but it doesn't work, i get:
Error binding parameter 0 - probably unsupported type.
I will be thankful for any hint how i could optimize it or solve of course too - more thankful :)
If it's not working, you can't optimize it. First make it work.
At first glance, it seems that you have really mixed concepts about fields, relationships and equality/membership. First go thought the docs, and build your query piece by piece on the python shell (likely from the inside out).
Just a shot in the dark:
all_accepted_parts = acceptedFragment.objects.filter(fragment__in = fragment.objects.filter(categories = fragmentCategory.objects.get(id=1)))
or maybe:
all_accepted_parts = acceptedFragment.objects.filter(fragment__in = fragment.objects.filter(categories = 1))
As others have said, we really need the models, and some explanation of what you're actually trying to achieve.
But it looks like you want to do a related table lookup. Rather than getting all the related objects in a separate nested query, you should use Django's related model syntax to do the join within your query.
Something like:
acceptedFragment.objects.filter(fragment__categories__id = 1)

Categories

Resources