Django: distinct

I know there is distinct() function in Django ORM. However, it is used differently for each type of database. In this case, my application is using PostgreSQL but our unit test is using SQLite. So yeah good luck with it.

Some example using distinct:

YourModel.objects.distinct() # distinct for all combinations of columns in the table
YourModel.objects.distinct("a_column") # distinct only for a specific column

But as I mentioned, that our unit test is using SQLite. And only the first example is working for other than PostgreSQL. If we use the second example for our sql lite, it will throw this error 

DISTINCT ON fields is not supported by this database backend

So, what should we do if we just want to do distinct for a specific column in other database other than PostgreSQL? Then we can use values() or value_list() such as:

YourModel.objects.values("a_column").distinct()

We probably think that it will be translated to 

SELECT DISTINCT "YourModel"."a_column" FROM "YourModel"

But surprisingly, it is not the case. So if YourModel has defined the ordering in its Meta. Then this ordering will be included in the select distinct query. Okay for example, YourModel has ordering to ‘modified’, then the modified will be included into the query such as below:

class YourModel(models.Model):
    a_column = models.TextField()
    modified = models.TextField()

    class Meta:
        ordering = [ 'modified', ]

YourModel.objects.values("a_column").distinct()

# will be translated to 
SELECT DISTINCT "YourModel"."a_column", "YourModel"."modified" FROM "YourModel" ORDER BY "YourModel"."modified"

So the solution/workaround is actually simple. We just need to add order_by with nothing on it. 

YourModel.objects.values("a_column").distinct().order_by()

# will be translated to 
SELECT DISTINCT "YourModel"."a_column" FROM "YourModel" 

Happy coding!

Django: AttributeError – select_related

AttributeError: 'YourObject' object has no attribute 'select_related'

If you received this error, first check how you build up your django query. I had this error because I mis-structured it. 

what I did:

MyModel.objects.filter(somequery=somevalue).select_related(myrelation)

But what I should do:

MyModel.objects.select_related(myrelation).filter(somequery=somevalue)