【问题标题】:implementing save draft/publish feature in django blog model在 django 博客模型中实现保存草稿/发布功能
【发布时间】:2021-03-25 21:38:25
【问题描述】:

所以我用 Django 构建了一个非常基本的博客。我一直在努力添加一项新功能,允许我将新帖子保存为草稿以便稍后发布,或取消发布已发布的帖子。我对 Django/Python 还很陌生,所以也许我在这里犯了一个新手错误。

为了实现这一点,我在我的 Post 模型中添加了两个字段。一个名为 publishedBooleanField 和一个名为 publish_dateDateTimeField。我只希望 publish_datepublish 设置为 True 且之前为 False 时更新。我采用的方法是覆盖我的 Post 模型的 save() 方法。在该方法中,我将 publish_date 设置为 None(如果 published 在表单上未选中)或者我将 publish_date 设置为时区.now()(如果 published 在表单上被选中)。

这种方法没问题,虽然 publish_date 会在每次更新帖子时更新,即使它没有被取消发布/重新发布。这不可能发生。我仍在学习视图、模型和表单之间的交互,因此非常感谢任何指导。

请查看所有相关代码,让我知道解决此问题的更好方法。感谢您的帮助!

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'}),
        }

【问题讨论】:

    标签: python django django-models model-view-controller


    【解决方案1】:

    为避免每次更新帖子时 publish_date 都会更新,即使它没有被取消发布/重新发布,您应该检查 self.published 的新值是否与以前相比已更改,如果更改,请执行您的代码。

    Django 本身并没有为您提供简单的工具来检查值是否已更改,因此您必须使用this question 的一些答案。

    【讨论】:

    • 谢谢你。我早些时候发现了这个问题,并试图解决它无济于事,但你的评论让我确信这是正确的方向。我会继续努力。谢谢!
    • 这是解决方案,我需要更仔细地查看那里接受的答案中其他一些用户的 cmets。谢谢!
    【解决方案2】:

    您可以避免一直使用已发布,并将发布日期设置为“发布”帖子。

    from django.utils import timezone
    from django.utils.functional import cached_propery
    
    class Post(models.Model):
        # ...
        publish_date = models.DateTimeField(blank=True, null=True, default=None)
        
        @cached_property
        def is_published(self):
            return self.publish_date <= timezone.now()
        
        def publish(self):
            self.publish_date = timezone.now()
    

    检查是否在模板中发布:

    {% if post.is_published %}
        <span>Published!</span>
    {% endif %}
    

    发布帖子:

    post = Post()
    post.publish()
    post.save()
    

    所有已发布帖子的查询集:

    Post.objects.filter(publish_date__isnull=False).all()
    

    相反,尚未发布的帖子:

    Post.objects.filter(publish_date__isnull=True).all()
    

    在查询集中发布所有帖子:

    Post.objects.update(publish_date=timezone.now())
    

    甚至,您可以实现未来的发布,例如3 天内:

    Post.objects.update(publish_date=timezone.now() + timezone.timedelta(days=3))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-13
      • 1970-01-01
      • 2013-06-29
      • 2018-07-13
      • 1970-01-01
      • 2014-04-15
      • 2015-01-10
      • 2012-10-31
      相关资源
      最近更新 更多