J'ai un champ dans le modèle roll_numb. Le roll_numb a des valeurs comme suit.

070-001
070-007
070-343
080-002
080-008

Quand i order_by roll_numb le tri est comme ci-dessus. Je veux diviser le roll_numb par - et trier par le reste. (c'est-à-dire 001, 002, 008)

Code

class Meta:
        ordering = ['roll_numb']
6
A.J. 1 janv. 2016 à 22:03

2 réponses

Meilleure réponse

Je pense qu'il n'est pas possible de commander un queryset par la méthode de model dans la portée ORM de Django.

Donc, pour trier votre queryset par votre méthode personnalisée, je recommande 2 méthodes:

D'abord

qs = mymodel.objects.all()
qs = sorted(qs, key: lambda i: i.roll_numb().split('-')[1])

Deuxième

Ajoutez un autre champ à votre modèle, alors activez l'ORM de Django pour trier par la valeur souhaitée:

MyModel(models.Model):
    class Meta:
        ordering = ['roll_numb_splitted']

   roll_numb_splitted = models.Charfield(max_length=3)

   def save(self, *args, **kwargs):
        # this is a check to run once
        if not self.pk:
            self.roll_numb_splitted = self.roll_numb().split('-')[1]
        return super(MyModel, self).save(*args, **kwargs)
5
kia 1 janv. 2016 à 19:19

Annotez votre jeu de requêtes avec un champ personnalisé:

from django.db.models.functions import Substr

YourModel.objects.annotate(roll_split=Substr('roll_numb', 5)).order_by('roll_split')

Si vous souhaitez toujours commander vos modèles, déplacez simplement cette annotation vers le gestionnaire de modèles:

class YourModelManager(models.Manager):
    def get_queryset(self):
        qs = super(YourModelManager, self).get_queryset()
        return qs.annotate(roll_split=Substr('roll_numb', 5)).order_by('roll_split')

class YourModel(models.Model):
    objects = YourModelManager()
7
Alex Morozov 1 janv. 2016 à 20:24