Get Django to return only the first 50 characters of text stored as a models.TextField()
Question:
In Python Crash Course chapter 18 we make a Learning Log website.
I can’t make this return just the first 50 characters of a >50 character long entry when I go into the Learning Log website that we make (through localhost:8000). It doesn’t show the ellipsis either, it just shows the whole entry.
from django.db import models
from django.contrib.auth.models import User
class Topic(models.Model):
"""A topic the user is learning about"""
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
"""Return a string representation of the model."""
return str(self.text)
class Entry(models.Model):
"""Something specific learned about a topic"""
topic = models.ForeignKey(Topic, on_delete=models.PROTECT)
text = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'entries'
def __str__(self):
"""Return a string representation of the model."""
if len(self.text) > 50:
return f"{str(self.text)[:50]}..."
else:
return f"{str(self.text)}"
It is the same whether I include the if len(self.text) > 50
statement or not.
My code differs somewhat from the book in that:
- I use
on_delete=models.PROTECT
, as I understand that CASCADE
can cause weird issues like accidentally getting something
deleted that you didn’t intend to delete
- I use
str(self.text)
instead of just self.text
in the __str__
definitions; if I don’t it raises a pylint error "Value ‘self.text’ is unsubscriptable". I can still make entries without the str()
conversion – it still won’t show only the first 50 characters however.
Is it something about how models.TextField()
function that causes this? Am I supposed to have to do the str()
conversions to make the self.text
variable "subscriptable"?
Answers:
In Django 3.0 models.TextField
returns a string(str
) if you call it as self.text
or Entry.text
. So you don’t need to call str()
function.
If you want to get first 50 characters:
def __str__(self):
return self.text[:50]
In Python if you use [:50]
for a subscriptable object, it will return first 50 parts (or all if it have less than 50 parts) of the object.
I wish my answer helps you.
According to what I see you can just say
def __str__(self):
return self.text[:50]
but also
You can use truncate word filter when calling it in the HTML form
You did not show the views.py but say you have a view that returns to a page all the Entries in the Entry Class you and you happen to say
{% for Entry in Entries %}
you would just add
{{ Entry:text|truncatewords:50 }}
{% endfor %}
you can learn more at The Docs
Also you can do this:
def __str__(self):
if self.text[50:]:
return f"{self.text[:50]}..."
else:
return f"{self.text[:50]}"
def __str__(self):
"""Return a string representation of the model."""
if len(self.text) > 50:
return f"{str(self.text)[:50]}..."
else:
return f"{str(self.text)}"
This function gives you the first 50 characters, please remove and run your program.
Textfield support unlimited text in this field.
In Python Crash Course chapter 18 we make a Learning Log website.
I can’t make this return just the first 50 characters of a >50 character long entry when I go into the Learning Log website that we make (through localhost:8000). It doesn’t show the ellipsis either, it just shows the whole entry.
from django.db import models
from django.contrib.auth.models import User
class Topic(models.Model):
"""A topic the user is learning about"""
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
"""Return a string representation of the model."""
return str(self.text)
class Entry(models.Model):
"""Something specific learned about a topic"""
topic = models.ForeignKey(Topic, on_delete=models.PROTECT)
text = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'entries'
def __str__(self):
"""Return a string representation of the model."""
if len(self.text) > 50:
return f"{str(self.text)[:50]}..."
else:
return f"{str(self.text)}"
It is the same whether I include the if len(self.text) > 50
statement or not.
My code differs somewhat from the book in that:
- I use
on_delete=models.PROTECT
, as I understand that CASCADE
can cause weird issues like accidentally getting something
deleted that you didn’t intend to delete - I use
str(self.text)
instead of justself.text
in the__str__
definitions; if I don’t it raises a pylint error "Value ‘self.text’ is unsubscriptable". I can still make entries without thestr()
conversion – it still won’t show only the first 50 characters however.
Is it something about how models.TextField()
function that causes this? Am I supposed to have to do the str()
conversions to make the self.text
variable "subscriptable"?
In Django 3.0 models.TextField
returns a string(str
) if you call it as self.text
or Entry.text
. So you don’t need to call str()
function.
If you want to get first 50 characters:
def __str__(self):
return self.text[:50]
In Python if you use [:50]
for a subscriptable object, it will return first 50 parts (or all if it have less than 50 parts) of the object.
I wish my answer helps you.
According to what I see you can just say
def __str__(self):
return self.text[:50]
but also
You can use truncate word filter when calling it in the HTML form
You did not show the views.py but say you have a view that returns to a page all the Entries in the Entry Class you and you happen to say
{% for Entry in Entries %}
you would just add
{{ Entry:text|truncatewords:50 }}
{% endfor %}
you can learn more at The Docs
Also you can do this:
def __str__(self):
if self.text[50:]:
return f"{self.text[:50]}..."
else:
return f"{self.text[:50]}"
def __str__(self):
"""Return a string representation of the model."""
if len(self.text) > 50:
return f"{str(self.text)[:50]}..."
else:
return f"{str(self.text)}"
This function gives you the first 50 characters, please remove and run your program.
Textfield support unlimited text in this field.