I need to order_by a field comparison such that all fields matching a certain value are displayed at the top.
The SQL to do this is SELECT * FROM messages ORDER BY message='alsfkjsag' DESC
There are at least two ways to do it:
Custom SQL with UNION:
combine two selects
one who contains all rows which have your desired message
the other with all rows who have another message
Add a dynmaic Field to the QuerySet
extra(select={"is_message":"message='alsfkjsag'"})
and then order_by('is_message')
or in short:
Messages.objects.extra(select={"is_message":"message='alsfkjsag'"})
.order_by('is_message')
Related
I have a table which same as bellow
id|user|datetime|action
this table records actions for each user and its time I want to get latest actions which are done by all users. I have tested these methods
Entry.objects.order_by('datetime','user').distinct('user')
and
Entry.objects.latest('datetime').distinct('user')
but both of them returns errors. for example the second try says :
SELECT DISTINCT ON expressions must match initial ORDER BY expressions
How can I filter rows by latest actions which are done by all users?
Try with below code:
Entry.objects.all().order_by('user', '-datetime').distinct('user')
From django doc we have :
When you specify field names, you must provide an order_by() in the QuerySet, and the fields in order_by() must start with the fields in distinct(), in the same order.
I have a Message class which has fromUser, toUser, text and createdAt fields.
I want to imitate a whatsapp or iMessage or any SMS inbox, meaning I want to fetch the last message for each conversation.
I tried:
messages = Message.objects.order_by('createdAt').distinct('fromUser', 'toUser')
But this doesn't work because of SELECT DISTINCT ON expressions must match initial ORDER BY expressions error.
I don't really understand what it means, I also tried:
messages = Message.objects.order_by('fromUser','toUser','createdAt').distinct('fromUser', 'toUser')
and such but let me not blur the real topic here with apparently meaningless code pieces. How can I achieve this basic or better said, general well-known, result?
Your second method is correct. From the Django docs:
When you specify field names, you must provide an order_by() in the QuerySet, and the fields in order_by() must start with the fields in distinct(), in the same order.
For example, SELECT DISTINCT ON (a) gives you the first row for each value in column a. If you don’t specify an order, you’ll get some arbitrary row.
This means that you must include the same columns in your order_by() method that you want to use in the distinct() method. Indeed, your second query correctly includes the columns in the order_by() method:
messages = Message.objects.order_by('fromUser','toUser','createdAt').distinct('fromUser', 'toUser')
In order to fetch the latest record, you need to order the createdAt column by descending order. The way to specify this order is to include a minus sign on the column name in the order_by() method (there is an example of this in the docs here). Here's the final form that you should use to get your list of messages in latest-first order:
messages = Message.objects.order_by('fromUser','toUser','-createdAt').distinct('fromUser', 'toUser')
At the moment I have a query that selects distinct values from a model:
Meeting.objects.values('club').distinct()
In addition to the 'club' field, I also wish to select a 'time' field. In other words I wish to select distinct values of the 'club' field and the associated 'time' field. For example for:
CLUB,TIME
ABC1,10:35
ABC2,10:45
ABC2,10:51
ABC3,11:42
I would want:
ABC1,10:35
ABC2,10:45
ABC3,11:42
What is the syntax for this?
This is possible, but only if your database backend is PostgreSQL. Here how it can be done:
Meeting.objects.order_by('club', 'time').values('club', 'time').distinct('club')
Look documentation for distinct
I have a model that has a field (lets call it this_field) which is stored as a string. The values in this_field are in the form Char### - as in, they have values such as: A4 or A34 or A55 (note that they will always have the same first character).
Is there a way to select all the records and order them by this field? Currently, when I do an .order_by('this_field') I get the order like this:
A1
A13
A2
A25
etc...
What I want is:
A1
A2
A13
A25
etc...
Any best approach methods or solutions to achieve this query set ordered properly?
Queryset ordering is handled by the database backend, not by Django. This limits the options for changing the way that ordering is done. You can either load all of the data and sort it with Python, or add additional options to your query to have the database use some kind of custom sorting by defining functions.
Use the queryset extra() function will allow you to do what you want by executing custom SQL for sorting, but at the expense of reduced portability.
In your example, it would probably suffice to split the input field into two sets of data, the initial character, and the remaining integer value. You could then apply a sort to both columns. Here's an example (untested):
qs = MyModel.objects.all()
# Add in a couple of extra SELECT columns, pulling apart this_field into
# this_field_a (the character portion) and this_field_b (the integer portion).
qs = qs.extra(select={
'this_field_a': "SUBSTR(this_field, 1)",
'this_field_b': "CAST(substr(this_field, 2) AS UNSIGNED)"})
The extra call adds two new fields into the SELECT call. The first clause pulls out the first character of the field, the second clause converts the remainder of the field to an integer.
It should now be possible to order_by on these fields. By specifying two fields to order_by, ordering applies to the character field first, then to the integer field.
eg
qs = qs.order_by('this_field_a', 'this_field_b')
This example should work on both MySql and SQLite. It should also be possible to create a single extra field which is used only for sorting, allowing you to specify just a single field in the order_by() call.
If you use this sort order a lot and on bigger tables you should think about two separate fields that contain the separated values:
the alpha values should be lowercased only, in a text or char field, with db_index=True set
the numeric values should be in an integer field with db_index=True set on them.
qs.order_by('alpha_sort_field', 'numeric_sort_field')
Otherwise you will probably experience some (or up to a huge) performance impact.
Another way of doing it is to sort the QuerySet based on the int part of this_field:
qs = ModelClass.objects.all()
sorted_qs = sorted(qs, key=lambda ModelClass: int(ModelClass.this_field[1:]))
I have a django model query that needs to fetch me the distinct rows from a particular table, but for some reason its not fetching it.
Let me know your inputs
Query
Volunteercontacts.objects.order_by('name')- gives me the expected answer ie;ordering by name
Volunteercontacts.objects.order_by('name').distinct('name')- does not eliminate the duplicate
You should differentiate between distinct Volunteercontacts models and distinct name column values.
For distinct Volunteercontacts models you can use distinct(), but in this case has no effect:
Volunteercontacts.objects.order_by('name').distinct()
For distinct columns values you can use a dictionary or array of value list:
Volunteercontacts.objects.values_list('name',
flat=True).order_by('name').distinct()
Also, remember that the ability to specify field names in distinct method is only available in PostgreSQL.
Django 1.4 provides the expected behaviour in the original question (assuming you are using Posgtres):
https://docs.djangoproject.com/en/1.4/ref/models/querysets/#distinct