使用createview和modelform在django中自动将登录用户设置为作者 [英] Automatically set logged-in user as the author in django using createview and modelform

查看:71
本文介绍了使用createview和modelform在django中自动将登录用户设置为作者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个前端表单,该表单允许某人无需访问管理员即可发布文章。

I am building a frontend form that allows someone to post an article without accessing the admin.

用户登录后,我希望他/她才能写一篇文章。保存后,我希望该用户自动设置为该文章的作者。

When the user is logged in, I would like for him/her to be able to write an article. Upon saving, I would like that user to automatically be set as the author of the article.

我陷入了僵局。

models.py

models.py

from django.db import models

from django.urls import reverse
from django.contrib.auth.models import User
from django.utils import timezone



class Article(models.Model):
    author = models.ForeignKey(User)
    title = models.CharField(max_length=65)
    text = HTMLField()
    created_date = models.DateTimeField(default=timezone.now)
    published_date = models.DateTimeField(blank=True, null=True)

    def publish(self):
        self.published_date = timezone.now()
        self.save()

    def __str__(self):
        return self.title


class ArticleImage(models.Model):
    image = CloudinaryField('image')
    image_name = models.CharField(max_length=55,
                                    default='')
    article = models.ForeignKey(Article)

    def __str__(self):
        return self.image_name


class ArticleTag(models.Model):
    slug = models.SlugField(max_length=50,
                            unique=True)
    article = models.ForeignKey(Article)

    def __str__(self):
        return self.slug


class ArticleCategory(models.Model):
    slug = models.SlugField(max_length=20,
                            unique=True)
    article = models.ForeignKey(Article)

    def __str__(self):
        return self.slug

forms.py

class ArticleCreationForm(ModelForm):

    class Meta:
        model = Article
        fields = ['title', 'text']
        widgets = {
            'title': forms.TextInput(attrs={'placeholder': 'Please add a title. Max: 65 characters'}),
            'text': forms.Textarea(attrs={'cols': 80, 'rows': 40, 'placeholder': 'Starting typing your article...'})
        }

ArticleImageFormSet = inlineformset_factory(Article, ArticleImage,
                                            fields=('image', 'image_name',),
                                            extra=1,
                                            max_num=1,
                                            widgets={'image_name':
                    forms.TextInput(attrs={'placeholder': 'Image name'})})
ArticleTagFormSet = inlineformset_factory(Article, ArticleTag,
                                            fields=('slug',),
                                            extra=1,
                                            max_num=1)
ArticleCategoryFormSet = inlineformset_factory(Article, ArticleCategory,
                                            fields=('slug',),
                                            extra=1,
                                            max_num=1)

views.py

class CreateArticle(CreateView):
    model = Article
    form_class = ArticleCreationForm
    template_name_suffix = '_add_form'

    def get_success_url(self):
        return reverse('accounts:detail', kwargs={'pk': self.object.pk})

    def get(self, request, *args, **kwargs):
        """
        Handles GET requests and instantiates blank versions of the form
        and its inline formsets.
        """
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        articleimage_form = ArticleImageFormSet()
        articletag_form = ArticleTagFormSet()
        articlecategory_form = ArticleCategoryFormSet()
        return self.render_to_response(
            self.get_context_data(form=form,
                                  articleimage_form=articleimage_form,
                                  articletag_form=articletag_form,
                                  articlecategory_form=articlecategory_form))

    def post(self, request, *args, **kwargs):
        """
        Handles POST requests, instantiating a form instance and its inline
        formsets with the passed POST variables and then checking them for
        validity.
        """
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        articleimage_form = ArticleImageFormSet(self.request.POST)
        articletag_form = ArticleTagFormSet(self.request.POST)
        articlecategory_form = ArticleCategoryFormSet(self.request.POST)
        if (form.is_valid() and articleimage_form.is_valid() and
            articletag_form.is_valid() and articlecategory_form.is_valid()):
            return self.form_valid(form, articleimage_form, articletag_form,
                                    articlecategory_form)
        else:
            return self.form_invalid(form, articleimage_form, articletag_form,
                                        articlecategory_form)

    def form_valid(self, form, articleimage_form, articletag_form,
                    articlecategory_form):
        """
        Called if all forms are valid. Creates a Recipe instance along with
        associated Ingredients and Instructions and then redirects to a
        success page.
        """
        self.object = form.save()
        obj.author = request.user.username
        articleimage_form.instance = self.object
        articleimage_form.save()
        articletag_form.instance = self.object
        articletag_form.save()
        articlecategory_form.instance = self.object
        articlecategory_form.save()
        return HttpResponseRedirect(self.get_success_url())

    def form_invalid(self, form, articleimage_form, articletag_form,
                        articlecategory_form):
        """
        Called if a form is invalid. Re-renders the context data with the
        data-filled forms and errors.
        """
        return self.render_to_response(
            self.get_context_data(form=form,
                                  articleimage_form=articleimage_form,
                                  articletag_form=articletag_form,
                                  articlecategory_form=articlecategory_form))

template.html

template.html

<form enctype="multipart/form-data" action="" method="post">
            {% csrf_token %}
            <div class="row">
              <div class="medium-9 columns">
                {{ form.non_field_errors }}
                <h2 class="article-identifier">Add a new article</h2>
                <div class="fieldWrapper">
                  {{ form.title.errors }}
                  {{ form.title }}
                  <div id="title_feedback" class="text-right"></div>
                </div>

                <div class="fieldWrapper">
                  {{ form.text.errors }}
                  {{ form.text }}
                </div>
              </div>
              <div class="medium-3 columns">
                <div class="button-wrapper">
                  <input class="button" type="submit" value="Publish">
                </div>

                <fieldset class="image_upload">
                  <h2>Add an Image</h2>
                    {{ articleimage_form.management_form }}
                    {{ articleimage_form.non_form_errors }}
                    {% for form in articleimage_form %}
                        {{ form.id }}
                          <div class="inline {{ articleimage_form.prefix }}">
                              {{ form.image.errors }}
                              {{ form.image.label_tag }}
                              {{ form.image }}
                              {{ form.image_name.errors }}
                              {{ form.image_name.label_tag }}
                              {{ form.image_name }}
                          </div>
                    {% endfor %}
                </fieldset>

                <fieldset>
                  <h2>Add a Category</h2>
                  {{ articlecategory_form.management_form }}
                  {{ articlecategory_form.non_form_errors }}
                  {% for form in articlecategory_form %}
                      {{ form.id }}
                      <div class="inline {{ articlecategory_form.prefix }}">
                          {{ form.slug.errors }}
                          {{ form.slug.label_tag }}
                          {{ form.slug }}
                      </div>
                  {% endfor %}
                </fieldset>

                <hr />

                <fieldset>
                  <h2>Add a Tag</h2>
                  {{ articletag_form.management_form }}
                  {{ articletag_form.non_form_errors }}
                  {% for form in articletag_form %}
                      {{ form.id }}
                      <div class="inline {{ articletag_form.prefix }}">
                          {{ form.slug.errors }}
                          {{ form.slug.label_tag }}
                          {{ form.slug }}
                      </div>
                  {% endfor %}
                </fieldset>

              </div>
            </div>
        </form>


推荐答案

使用 commit保存表单= False ,在对象上设置用户,然后保存对象。在 form_valid 方法内,您可以使用 self.request.user 访问该用户。您应该分配用户实例,而不是像当前代码那样分配用户名。

Save the form with commit=False, set the user on the object, then save the object. Inside the form_valid method, you can access the user with self.request.user. You should assign the user instance, not the username as your code currently does.

obj = form.save(commit=False)
obj.author = self.request.user
...
obj.save

还应该将视图限制为登录用户。您可以为此使用 LoginRequiredMixin

You should also restrict the view to logged in users. You can use the LoginRequiredMixin for this.

from django.contrib.auth.mixins import LoginRequiredMixin

class CreateArticle(LoginRequiredMixin, CreateView):

这篇关于使用createview和modelform在django中自动将登录用户设置为作者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆