0

誰かが管理者にアクセスせずに記事を投稿できるようにするフロントエンドフォームを構築しています。createviewとmodelformを使用してログインしているユーザーをdjangoの著者として自動的に設定しました

ユーザーがログインしているときに、記事を書くことができるようにしたいと思います。保存すると、そのユーザーが記事の著者として自動的に設定されるようにしたいと思います。

私は窮屈です。どんな助けでも大歓迎です。

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

<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> 

答えて

2

保存commit=Falseとフォームに隠し入力を追加設定したユーザを対象に、そのオブジェクトを保存しようとすることができます。 form_validメソッド内では、self.request.userでユーザーにアクセスできます。現在のコードと同じように、ユーザーインスタンスではなくユーザーインスタンスを割り当てる必要があります。

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

ログインしたユーザーにも表示を制限する必要があります。これにはLoginRequiredMixinを使用できます。

from django.contrib.auth.mixins import LoginRequiredMixin 

class CreateArticle(LoginRequiredMixin, CreateView): 
+0

ありがとうございます。これは動作します! – user2901792

-1

あなたは、あなたのフォームテンプレート

<form> 
.... 
    <input type="hidden" name="author" value="{{ request.user.id }}"> 
</form> 
+3

htmlに関する知識がほとんどない人は、この値を変更して矛盾したデータになる可能性があります。バックエンドでこれを処理する方が良いでしょう。 – dnit13

関連する問題