Reputation: 95
I'm building a blog website with Django, and for posts on the blog I want to have 2 pages, first page would be the page where all the posts are displayed as a list, and the second would be a page for a specific post, with all the details. On the first page I want to show every post with title, date, and a part of the post's text. I thought that I can add to the post model another field which'll hold a substring from the hole post's text. My post model is this:
class Post(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=500)
content = models.TextField()
display_content = models.TextField(blank=True)
tags = models.CharField(max_length=100)
date_posted = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.title
I want for every post the display_content field to hold the first 167 characters from the content field + "...", and I'm not sure that I'd have to implement something directly on the class Post, maybe a function, or if I need to make this operation on the view function that renders this page with posts.
Upvotes: 1
Views: 627
Reputation: 476554
You can define the logic in the __str__
method, but it might be better to define a utility function that you can later reuse:
def shorten(text, max_len=167):
if len(text) <= max_len:
return text
else:
return '{}…'.format(text[:max_len])
Note that an ellipsis character ('…'
) [wiki] is a single character, and normally not three inidividual dots.
Then we can use this in the __str__
method:
from django.conf import settings
class Post(models.Model):
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
title = models.CharField(max_length=500)
content = models.TextField()
display_content = models.TextField(blank=True)
tags = models.CharField(max_length=100)
date_posted = models.DateTimeField(auto_now_add=True)
def __str__(self):
return shorten(self.title)
For templates, Django already has a |truncatechars
template filter. So if you plan to render this in a template, there is no need to implement this logic in the model. You can render the title then with:
{{ mypost.title|truncatechars:167 }}
This makes more sense, since a Django model should not be concerned with how to render data, a model deals with storing, and modifying data.
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL
[Django-doc] to refer to the user model, than to use theUser
model [Django-doc] directly. For more information you can see the referencing theUser
model section of the documentation.
Note: Django's
DateTimeField
[Django-doc] has aauto_now_add=…
parameter [Django-doc] to work with timestamps. This will automatically assign the current datetime when creating the object, and mark it as non-editable (editable=False
), such that it does not appear inModelForm
s by default.
Upvotes: 1