Reputation: 25
My main code is this:
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_posts')
updated_on = models.DateTimeField(auto_now=True)
image = models.ImageField(upload_to='images/%Y/%m/%d/', blank=True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
publishdate = created_on.strftime('%Y/%m')
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
When I run this code, I get:
'DateTimeField' object has no attribute 'strftime'
referring to publishdate
strftime works with datetime.datetime, and DateTimeField converts to datetime.datetime, so what am I doing wrong?
I've tried to convert to datetime.datetime to no avail
EDIT: Having seen answers, I think I should verify what I'm trying to do
I'm trying to add the date to this url in urls.py:
urlpatterns = [
path('', views.PostList.as_view(), name='home'),
path('<publishdate>/<slug:slug>', views.PostDetail.as_view(), name='post_detail'
]
EDIT 2: I've updated my code to this:
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_posts')
updated_on = models.DateTimeField(auto_now=True)
image = models.ImageField(upload_to='images/%Y/%m/%d/', blank=True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
created_on_string = created_on.value_to_string(created_on)
publishdate = strptime(created_on_string, '%Y/%m')
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
and the output is:
File "C:\Users\[user]\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\fields\__init__.py", line 933, in value_from_object
return getattr(obj, self.attname)
AttributeError: 'DateTimeField' object has no attribute 'attname'
Upvotes: 2
Views: 1831
Reputation: 476594
At the class level, created_on
is a DateTimeField
, not the datetime
object a Post
object (not the class) holds. If you want to add a property that formats it, you can use:
class Post(models.Model):
# …
created_on = models.DateTimeField(auto_now_add=True)
@property
def publishdate(self):
return self.created_on.strftime('%Y/%m')
# …
That being said, formatting data is usually not the task of a model. A model is used to store and represent data. In a template you can for example use the |date
template tag [Django-doc] to format a datetime
object in a specified format. For a given Post
object post
, you for example can format this as:
{{ post.created_on|date:'Y/m' }}
For the URL, you can use two parameters:
urlpatterns = [
path('', views.PostList.as_view(), name='home'),
path(
'<int:year>/<int:month>/<slug:slug>',
views.PostDetail.as_view(),
name='post_detail'
)
]
in your view you then filter with:
class PostDetail(DetailView):
model = Post
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(
created_on__year=self.kwargs['year'],
created_on__month=self.kwargs['month']
)
In a template, you can then link to the view with a post
object with:
{% url 'post_detail' post.created_on.year post.created_on.month post.slug %}
Upvotes: 3
Reputation: 1710
Shouldn't it work by adding a self
to the attribute at the class level?
publishdate = self.created_on.strftime('%Y/%m')
Upvotes: 0