1

I'm trying to understand what is the ordering logic of django of DateField in case the dates are equal? I've got a model that has a DateField and DateTimeField (irrelevant fields taken out).

class Ad(models.Model):
    title = models.CharField(max_length=50)
    content = models.TextField()
    created_at = models.DateField(default=timezone.now)
    created_time = models.DateTimeField(default=timezone.now)

The ordering for the model is as such:

class Meta:
    ordering = ['-created_time', '-created_at']

Note that previously I didnt have the created_time = models.DateTimeField(default=timezone.now) at all and sorted only via -created_at. I added the additional DateTimeField just for testing purposes and it didnt affect the outcome of the DateField ordering in any way.

Here you can see the order how the objects were created in DB: enter image description here

And this is the order how the objects are actually ordered on the ListView page:

enter image description here

The slug field in DB can be used as reference in order to understand which object in the template corresponds to which object in the DB.

As you can see the first DateTimeField order works as expected, however the ordering by DateField is not the same as the order in the DB.

What is more interesting that if I will go to my UpdateView and update the "Summernote" objects content (not messing with dates) then the ordering again changes although the dates and times in DB were not changed.

See the order difference after each update of the object (each column is a different snapshot from the same view after updating the object): enter image description here

No changes to DB to illustrate that nor DateField nor DateTimeField were changed after updating the object: enter image description here

I have a custom queryset in my ListView but it is not affecting the ordering as far as I can tell

def get_queryset(self):

    shifts = re.findall('standard|shifts|other', self.request.path)
    queryset = super(ListAd, self).get_queryset()
    queryset = queryset.filter(city=self.kwargs['city'], category=self.kwargs['category'],
                               shift__in=shifts,
                               expire__gte=date.today(),
                               publish_status=True)
    return queryset

Why the strange and seemingly inconsistent ordering in case of equal dates? What other aspects does django take in to consideration when ordering objects that have equal DateField values? DB engine is PostgreSQL 13.1

d1spstack
  • 930
  • 1
  • 5
  • 16
  • If you do `print(queryset.query)` you can see if there is some more ordering happening. – Ruud van den Boomen Feb 07 '22 at 18:02
  • 1
    This behavior seems to be more on the database engine rather than django. You might want to add tags with your specific database so those who know more about your database might be able to answer – Brian Destura Feb 07 '22 at 22:51
  • @RuudvandenBoomen queryset.query returns the ordering as is in the model - ORDER BY "ads_ad"."created_time" DESC, "ads_ad"."created_at" DESC – d1spstack Feb 08 '22 at 09:40
  • 1
    @BrianDestura thank you for leading to think about the DB engine rather then django in this case. I found the answer in here https://stackoverflow.com/questions/11263715/is-postgresql-order-fully-guaranteed-if-sorting-on-a-non-unique-attribute Postgres doesnt have any ordering by itself, meaning that the result is somewhat random in case of equal values. A solution would be to add a 3rd ordering argument such as object.id – d1spstack Feb 08 '22 at 09:56

0 Answers0