Как обойти запрос конечного пользователя для имени пользователя при добавлении сообщения в блоге с помощью формы и автоматически отображать зарегистрированного пользователя как автора сообщения? - PullRequest
1 голос
/ 30 мая 2019

Я работаю над простым блогом, в котором есть модель Post.Я пытаюсь создать форму для добавления сообщений в блог (или добавления комментариев к сообщениям в этом отношении), чтобы конечным пользователям не приходилось заполнять поле формы, запрашивая у конечного пользователя имя пользователя.Я хотел бы иметь возможность просто запросить заголовок и основной текст сообщения в блоге, а когда оно будет опубликовано, оно будет опубликовано как аутентифицированный пользователь.

Я пытался не включать поле 'user' в поля в формах, но оно кажется обязательным.Может быть, мне нужно просто сделать это как-то скрытым с помощью виджетов?В шаблонах я мог бы написать следующее:

{% 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 Ответ

2 голосов
/ 30 мая 2019

Вы опускаете пользователя в PostForm:

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

или мы можем отобразить все поля, кроме 'user', например:

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

и затем вы добавляете пользователя к экземпляру в вашем представлении:

from django.shortcuts import <b>redirect</b>

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

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

    context = {
        'post_form': post_form,
    }

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

Таким образом, commit=False предотвращает сохранение объекта Post в базе данных.

Поскольку вы хотите загрузить image, вы должны также передать PostForm request.FILES [Django-doc] , иначе вы не будете обрабатывать загруженный файлы. Кроме того, вам нужно указать, что вы используете enctype="multipart/form-data" в своей форме:

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

Лучше использовать redirect [Django-doc] в случае успешного запроса POST, так как это шаблон Post / Redirect / Get [вики] . Предоставляя новую форму, если пользователь обновляет страницу, он / она создает второе сообщение, что, вероятно, не то, что вам нужно.

...