3

I am having a Django Model as shown below: I know that we can set the default ordering in the Meta class.

class Ingredient(models.Model):
    name = models.CharField(max_length=200,unique=True,null=False)
    slug = models.SlugField(unique=True)

    class Meta:
        ordering = ["name"]

As the ordering is set to name here. What i found is, it is ordering by case-sensitive. So how to make it case-insensitive

bhatt ravii
  • 382
  • 3
  • 12
Santhosh
  • 9,965
  • 20
  • 103
  • 243
  • 1
    Possible duplicate of [django-orm case-insensitive order by](https://stackoverflow.com/questions/3409047/django-orm-case-insensitive-order-by) – Clément Denoix Nov 17 '17 at 10:38
  • Its not duplicate. Here we are talking about the meta class. To know how to achieve that in Meta class. Or whether its possible or not – Santhosh Nov 17 '17 at 18:03

3 Answers3

11

I tested with django 2.0.7 and using Upper works :

class Ingredient(models.Model):
    class Meta:
        ordering = [Upper('name'), ]
name = models.CharField(max_length=200,unique=True,null=False)
Bryan Brancotte
  • 311
  • 3
  • 7
7

It's not possible set the default order to case-insensitive in the model meta options (source).

What you can do is use the order_by method of the QuerySet of your model:

from django.db.models.functions import Lower

Ingredient.objects.order_by(Lower('name'))

As stated already in this answer

To be able to have it as a default ordering (and avoid repeating the order_by method on each one of your querysets), you might want to create a custom Manager class for your Ingredient model:

# managers.py
from django.db.models.functions import Lower

class OrderedIngredientManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().order_by(Lower('name'))

# models.py
from .managers import OrderedIngredientManager

class Ingredient(models.Model):
    name = models.CharField(max_length=200,unique=True,null=False)
    slug = models.SlugField(unique=True)

    ordered_objects = OrderedIngredientManager()

So you can have all your QuerySet ordered:

Ingredient.ordered_objects.all()
Clément Denoix
  • 1,504
  • 11
  • 18
1

You can use it by using F from django models

from django.db.models import F
class Ingredient(models.Model):
    class Meta:
        ordering = [F('name').asc(nulls_last=True)]
DSAnup
  • 23
  • 7