Wincij
Wincij

Reputation: 111

Django "for" loop by date

I'm doing blog app. I did:

        {% for entry in entry.all %}
                <div class="timelinestamp">
                  ...
                </div>
                <br />
                <br />
                <br />
                <br />
        {% endfor %}

and almost everything works fine. I changed one Entry in my admin panel (The very first Entry...). Since then the order of my post has changed... Can anyone explain me why ? Or tell how to using loop render all Entries sorted by date ?

class Entry(models.Model):
    title = models.CharField(max_length=120)
    pub_date = models.DateField(null=False)
    body = models.TextField()
    image = models.ImageField(upload_to='images/', max_length = 100)

    def __str__(self):
        return self.title

The pub_date field is NOT primary key in my DB! I'm using Django 2.1

Upvotes: 1

Views: 2061

Answers (3)

Sanchit
Sanchit

Reputation: 316

If you have created model definition without the ordering meta option items in the database are not enforced any ordering, everytime when you do Model.objects.all() it will give you items without any order. If you want to queries to be in specific order you can:

  • Add ordering option to Meta options to model definition - which would require database migrations
  • Modify your query to enforce ordering like Model.objects.all().order_by('-pub_date') - also pass the query as context object to template like:
  • views.py -

    entries_by_pub_date = Model.objects.all().order_by('-pub_date') context['entries_by_pub_date'] = entries_by_pub_date

  • template

  • {% for entry in entries_by_pub_date %} ... {% enfor %}

Upvotes: 2

Rich Tier
Rich Tier

Reputation: 9441

From the docs:

If a query doesn’t have an ordering specified, results are returned from the database in an unspecified order. A particular ordering is guaranteed only when ordering by a set of fields that uniquely identify each object in the results. For example, if a name field isn’t unique, ordering by it won’t guarantee objects with the same name always appear in the same order.

It looks like you want to order by pub_date? Use ordering:

class Entry(models.Model):
    ...
    class Meta:
        ordering = ['-pub_date']

Upvotes: 2

S&#246;ren Weber
S&#246;ren Weber

Reputation: 589

As far as I can see you haven't defined a sort order for your Entry model. This means that you will process those entries in a non-defined order. To order your entries you could set a default sort order on Entry:

class Entry(models.Model):
    title = models.CharField(max_length=120)
    pub_date = models.DateField(null=False)
    body = models.TextField()
    image = models.ImageField(upload_to='images/', max_length = 100)

    def __str__(self):
        return self.title

    class Meta:
        ordering = ('-pub_date',)

Or, if that's not what you're looking for, you could order your queryset in your view:

Entry.objects.all().order_by('-pub_date')

Upvotes: 1

Related Questions