So I've built a very basic blog in Django. I have been working on adding a new feature allowing me to save a new post as a draft to publish later, or to unpublish an already published post. I'm fairly new to Django/Python, so perhaps I'm making a novice mistake here.
To achieve this, I've added two fields to my Post model. A BooleanField
named published and a DateTimeField
named publish_date. I only ever want publish_date to update when publish is set to True
& was previously False
. The approach I've taken is to override the save()
method of my Post model. Within the method, I am either setting publish_date to None
(if published is unchecked on the form) or I am setting publish_date to timezone.now() (if published is checked on the form).
This approach is okay, although publish_date will be updated everytime the post is updated, even if it has not been unpublished/republished. This cannot happen. I'm still learning about the interactions between views, models, and forms, so I really appreciate any guidance.
Please take a look at all relevant code and let me know of a better approach to solving this. Thank you for your help!
models.py
class Post(models.Model):
title = models.CharField(max_length=255)
body = RichTextUploadingField(blank=True, null=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
header_image = models.ImageField(upload_to="images/header_images/", default='images/header_images/default.jpg')
slug = models.SlugField(max_length=255, blank=True, null=True)
snippet = models.CharField(max_length=255)
created_date = models.DateTimeField(auto_now_add=True)
updated_date = models.DateTimeField(auto_now=True, blank=False, null=False)
publish_date = models.DateTimeField(auto_now_add=False, blank=True, null=True)
likes = models.ManyToManyField(User, related_name='blog_post', blank=True)
published = models.BooleanField()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('article-details', kwargs={"pk":self.pk,"slug":self.slug})
def total_likes(self):
return self.likes.count()
def save(self, *args, **kwargs):
if self.published == True:
self.publish_date = timezone.now()
else:
self.publish_date = None
super(FakePost, self).save(*args, **kwargs)
Forms.py
class ArticleNewForm(forms.ModelForm):
class Meta:
model = Post
fields = (
'title',
'slug',
'author',
'header_image',
'body',
'snippet',
'publish_date',
'published',
)
widgets = {
'title': forms.TextInput(),
'author': forms.TextInput(attrs={'class':'form-control', 'value':'','id':'userfield','type':'hidden',}),
'body': forms.Textarea(),
'snippet': forms.Textarea(),
'publish_date': DateTimeInput(attrs={'type': 'datetime-local'}),
}