Order_by in QuerySet do nothing

Hi all,

I use a ‘MonthArchiveView’ view with a ‘ListView’ Class.

I tried to sort my data with a ‘order_by’ in a QuerySet but the data is always sorting with the ‘DateField’ descending. I don’t understand what wong.
I have tried to change the field in order_by, tried with and without ‘-’…

Here my code

models

class PieceJointe(models.Model):

    date_text = models.DateField(default=timezone.now)
    titre_text = models.CharField(max_length=50)
    fichier_text = models.FilePathField(path = REPERTORY_PIECE_JOINTE, recursive = True)

    # Metadata
    class Meta:
        ordering = ['date_text']

    def get_absolute_url(self):
        return reverse('piece_jointe-update', args=[self.id])

    def __str__(self):
        return self.titre_text

views

class PieceJointeListView(MonthArchiveView):

    def get_month(self):
        try:
            month = super(PieceJointeListView, self).get_month()
        except Http404:
            month = now().strftime(self.get_month_format())

        return month
    
    def get_year(self):
        try:
            year = super(PieceJointeListView, self).get_year()
        except Http404:
            year = now().strftime(self.get_year_format())

        return year

    #model = PieceJointe
    template_name = "main/piece_jointe_list.html"
    date_field = "date_text"
    allow_future = True
    queryset = PieceJointe.objects.all().order_by('date_text')

templates

{% if object_list %}
          {% for obj in object_list %}
.....
           {% endfor %}
{% endif %}  

Any Ideas what wong ?
Thx

Hey there, can we at least see your error message code and your urls.py file of this issue you are having?

And please do rephrase your question on what you want the community to do for you, I find it difficult to comprehend. Thank you.

Hi Blaise-93,

Here my ‘urls.py

    path("piece_jointe/", views.PieceJointeListView.as_view(), name="piece_jointe"),
    path('piece_jointe/add/', views.PieceJointeCreate.as_view(), name='piece_jointe-create'),
    path('piece_jointe/<int:pk>/update/', views.PieceJointeUpdate.as_view(), name='piece_jointe-update'),    
    path('piece_jointe/<int:pk>/delete/', views.PieceJointeDelete.as_view(), name='piece_jointe-delete'),
    path("piece_jointe/<int:year>/<int:month>", views.PieceJointeListView.as_view(month_format='%m'), name="piece_jointe"),

I want ordering data in my views using ‘order_by’ in the queryset but nothing seem change in my views .
I thing something is wrong in my code but don’t know what ?

So, you want to sort it by date_text right? If yes, ascending or descending?

Yes that exact

When i use order_by(‘date_text’) or order_by(‘-date_text’), the result is the same.
If a use order_by(‘titre_text’) or order_by(‘-titre_text’), the result is yet the same, nothing change.

Ok, let me see what I can do on this issue, btw where did you get MonthArchiveView?. BRB

Or is it not ListView you are using?

In the views

from django.views.generic.dates import MonthArchiveView

Docs → Vues génériques basées sur les dates | Documentation de Django | Django

PieceJointeListView is juste the name of the class called in the urls.py

I changed the name of the class (PieceJointeMonthArchiveView) just in case, but same.

I believe def get_queryset() which you did not use is where your issue started coming from since you are dealing with CBV, ListView.

I think the code below could help you on what you are trying to achieve which I modified using your code and our series of conversation, Goodluck Dev!




from typing import Any, Sequence
from django.db.models.query import QuerySet

 # I don't know where you got your MonthArchiveView, use ListView if it is not being inherited 
 # from `ListView`  class
class PieceJointeListView(MonthArchiveView):
        #model = PieceJointe
    template_name = "main/piece_jointe_list.html"
    #date_field = "date_text"
    sort = None
    allow_future = True
    model = PieceJointe
    current_ordering = None
    #queryset = PieceJointe.objects.all().order_by('date_text')  => # it's not done this way

    def get_ordering(self, *args, **kwargs) -> Sequence[str]:
        """ Returns the ordering of PieceJointe from your db """
        
        if self.request.GET.get('ordering'):
            sort_by = self.request.GET['ordering']
            self.sort = sort_by
            
            if sort_by == 'fichier_text':
                sort_by = self.request.GET.get('sort_by', 'fichier_text')
            
            elif sort_by == 'titre_text':
                sort_by = self.request.GET.get('sort_by', 'titre_text')    

        else:
            sort_by = "date_text"
        return sort_by
    
    
            
    def get_queryset(self, *args,**kwargs) -> QuerySet[Any]:
        """ Returns all the queryset of the  PieceJointe for the client"""
        
        # queryset of the PieceJointe
        piece_jointe_qs = super(PieceJointeListView, self).get_queryset(*args, **kwargs)
        
        if self.request.GET:
            ordering = self.get_ordering(self)
            # current ordering for your model 
            self.current_ordering = ordering
            
            # let's set their respective order
            
            if 'date_text' in self.request.GET:
                self.date_text = self.request.GET['date_text'].split(',')
                piece_jointe_qs = piece_jointe_qs.filter(date_text__in=self.date_text)\
                    .order_by(self.current_ordering)
            
            # You can finish the rest of the code here I believe like titre_text
            
            return piece_jointe_qs     
        
    def get_month(self):
        try:
            month = super(PieceJointeListView, self).get_month()
        except Http404:
            month = now().strftime(self.get_month_format())

        return month
    
    def get_year(self):
        try:
            year = super(PieceJointeListView, self).get_year()
        except Http404:
            year = now().strftime(self.get_year_format())

        return year

Thx for your helps.

I have tested your code but it returned an internal server error.

I read again the last docs for ‘MonthArchiveView’ : MonthArchiveView -- Classy CBV and i finally founded a simply solution : Juste added a ‘ordering’ line like this :

class PieceJointeListView(MonthArchiveView):

    def get_month(self):
        try:
            month = super(PieceJointeListView, self).get_month()
        except Http404:
            month = now().strftime(self.get_month_format())

        return month
    
    def get_year(self):
        try:
            year = super(PieceJointeListView, self).get_year()
        except Http404:
            year = now().strftime(self.get_year_format())

        return year

    model = PieceJointe
    template_name = "main/piece_jointe_list.html"
    date_field = "date_text"
    ordering = "date_text" # ading this 
    allow_future = True

I am glad to hear that you had find away out of your problem.

I even forgot to even remove the MonthArchiveView and replace it with ListView
I will read more about it later.

1 Like