如何在使用表单添加博客帖子时绕过询问最终用户的用户名,并自动将登录用户显示为帖子作者?

时间:2019-05-30 12:49:22

标签: django django-forms django-views

我正在一个简单的博客中,该博客具有模型Post。我正在尝试创建一个表单,用于添加博客帖子(或为此添加评论),以便最终用户不必填写表格框,要求最终用户输入用户名。我希望能够仅要求博客文章的标题和正文,当点击文章时,它将以经过身份验证的用户身份发布。

我尝试在表单的字段中不包括“用户”字段,但这似乎是强制性的。也许我需要使用小部件将其隐藏起来?在模板中,我可以编写以下内容:

{% if user.is_authenticated %}
   <p>Posting as {{request.user}}</p>
{% else %}
   <p><a href={% url 'register' %}Please register to add a blog post</a></p>
{% endif %}

尽管我不确定,但我认为在views.py文件中包含逻辑会更有意义。

这是我的“ blog.models”文件:

class Post(models.Model):
    user            = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')
    title           = models.CharField(max_length=200)
    slug            = models.SlugField(unique=True)
    text            = models.TextField()
    published_date  = models.DateTimeField(auto_now=True)
    # pip install Pillow
    image           = models.ImageField(null=True, blank=True,
                                        upload_to='photos/%Y/%m/%d/',)


    def summary(self):
        """Return a summary for very long posts to
        get a glimpse from admin panel"""
        return self.text[:100]

    def _get_unique_slug(self):
        """Assigns a number to the end of a given slug field to prevent
        duplicated slug error. if title of a post is 'ayancik', and another
        user creates another post with the same title, second posts' slug
        is assigned a value: 'ayancik-2'"""
        slug = slugify(self.title)
        unique_slug = slug
        num = 1
        while Post.objects.filter(slug=unique_slug).exists():
            unique_slug = '{}-{}'.format(slug, num)
            num += 1
        return unique_slug

    def save(self, *args, **kwargs):
        """Automatically assign slug to objects
        by overriding save method"""
        self.slug = self._get_unique_slug()
        super().save(*args, **kwargs)

    def pub_date_pretty(self):
        return self.published_date.strftime('%b %e, %Y')

    def __str__(self):
        """String representation"""
        return self.title

    def get_absolute_url(self):
        # what does kwargs={'slug':self.slug} really achieve here?
        # where would we use 'key-value' pair?
        """Returns the url to access a detailed post"""
        return reverse('post-detail', kwargs={"slug": self.slug})

    class Meta:
        ordering = ['-published_date',]


class Comment(models.Model):
    post                = models.ForeignKey('blog.Post', on_delete=models.CASCADE,
                             related_name='comments')
    user                = models.CharField(max_length=200)
    text                = models.TextField()
    created_date        = models.DateTimeField(default=timezone.now)
    approved_comment    = models.BooleanField(default=False)

    def approve_comment(self):
        self.approved_comment = True
        self.save()

    def __str__(self):
        return self.text

“ blog.forms”文件:

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['user', 'title', 'text', 'image']

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ('user', 'text',)

和“ blog.views”文件:

@login_required
def create_post(request):
    if request.method == 'POST':
        post_form = PostForm(request.POST)

        if post_form.is_valid():
            post = post_form.save(request)
            post.save()
        else:
            print(post_form.errors)
    else:
            # when not POST request, display the empty form
            # meaning -> if request.method=='GET':
            post_form = PostForm()

    context = {
        'post_form': post_form,
    }

    return render(request, 'blog/addpost.html', context)

def add_comment_to_post(request, slug):
    post = get_object_or_404(Post, slug=slug)
    if request.method == 'POST':
        form = CommentForm(request.POST)

        if form.is_valid():
            comment = form.save(commit=False)
            comment.post = post
            comment.save()
            return redirect('post-detail', slug=slug)

    else:
        form = CommentForm()
    template_name = 'blog/add_comment_to_post.html'
    return render(request, template_name , {'form': form })

1 个答案:

答案 0 :(得分:2)

您在PostForm中省略了用户:

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        # no user
        fields = ['title', 'text', 'image']

或者我们可以显示除'user'以外的所有字段,例如:

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        exclude = ('user', )

,然后将用户添加到视图中的实例:

from django.shortcuts import redirect

@login_required
def create_post(request):
    if request.method == 'POST':
        post_form = PostForm(request.POST, request.FILES)

        if post_form.is_valid():
            post = post_form.save(commit=False)
            post.user = request.user
            post.save()
            return redirect('some_view')
    else:
        post_form = PostForm()

    context = {
        'post_form': post_form,
    }

    return render(request, 'blog/addpost.html', context)

commit=False从而阻止将该Post对象保存到数据库。

由于您要上传image,因此也应将request.FILES [Django-doc]传递给PostForm,否则将不会处理上传的文件。您还需要指定在表单中使用enctype="multipart/form-data"

<form enctype="multipart/form-data" method="POST" action="{% url 'create_post' %}">
    ...
</form>

在POST请求成功的情况下,最好使用redirect [Django-doc],因为这是Post/Redirect/Get pattern [wiki]。通过呈现新表单,如果用户刷新页面,他/她将创建第二条帖子,这可能不是您想要的。