Reputation: 157
I'm interested to filter table by django orm in specific order. Basically, it's simple search by two fields - name and description. I want to sort the result first by the "name" field concurrencies, and then by the "description" field concurrencies. Here is the example of raw sql:
WITH checkpoints AS (SELECT *
FROM checkpoints_view
WHERE ...)
SELECT *
FROM checkpoints
WHERE name ILIKE '%KEYWORD%'
UNION ALL SELECT *
FROM checkpoints
WHERE description ILIKE '%KEYWORD%' AND name NOT ILIKE '%KEYWORD%';
How can i generate sql like this in the django orm?
Thanks to all
P.S.: sorry for my english if i wasn't correct, i'm from not english-speaking country
class Checkpoint(models.Model, ReadOnlyModel):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=255, verbose_name='Наименование')
code_number = models.CharField(max_length=255, verbose_name="Код остановки")
description = models.CharField(max_length=255, verbose_name="Описание")
coordinate = models.PointField(verbose_name="Координата")
routes = ArrayField(models.IntegerField())
dates = ArrayField(models.DateField())
class Meta:
db_table = 'checkpoints_view'
managed = False
Almost all of you right, but i want to result was ordered at start by rows, which passes filter of name field, and then, after all this - rows, which passed filter of description field
Upvotes: 1
Views: 1748
Reputation: 15806
I think your code can be written without CTEs:
Checkpoint.objects.filter(
Q(name__icontains='keyword') |
(~Q(name__icontains='keyword') & Q(description__icontains='keyword')))
Upvotes: 2
Reputation: 5720
results = Checkpoint.objects.filter(
name__icontains='str_1',
) | Checkpoint.objects.filter(
description__icontains='str_2',
).exclude(
name__icontains='str_3',
)
Upvotes: 1
Reputation: 53734
AFAIK, the Django ORM does not use CTEs in the queries that it generates. That's because they have different behaviours across different RDBMS and not supported at all in mysql and sqlite.
So if you want to use a CTE in your query your only option is a raw query. Something like
queryset = MyModel.objects.raw('WITH checkpoints AS (SEL ....')
Upvotes: 1