7

models.py:

class BlogPost(models.Model):
    title = models.CharField(max_length=200)
    post_body = models.TextField()
    user = models.ForeignKey(User)
    pub_date = models.DateTimeField('published')

    def get_absolute_url(self):
        return u'/entries/%d' % self.id

forms.py:

class NewPostForm(forms.ModelForm):
    class Meta:
        model = BlogPost
        fields = ('title', 'post_body')

そこで、ユーザーが新しい投稿をブログに投稿するためのビューを作成しようとしていました。BlogPost モデルにはtitlepost_bodyuser、 の 4 つのフィールドがありpub_dateます。titleユーザーはとを入力できる必要がありますがpost_body、他の 2 つは自動的に入力される必要があります。私が最初に試したのはこれでした:

class NewPostView(generic.edit.CreateView):
    model = BlogPost
    form_class = NewPostForm

    def get_initial(self):
        return {'pub_date': timezone.now(),
                'user': self.request.user}

しかし、それが行う唯一のことは、html フォームのデフォルト値を提供することです。追加の調査の後、これは最終的に機能するコードです。

class NewPostView(generic.edit.CreateView):
    model = BlogPost
    form_class = NewPostForm

    def form_valid(self, form):
        obj = form.save(commit=False)
        obj.user = self.request.user
        obj.pub_date = timezone.now()
        obj.save()
        return HttpResponseRedirect(obj.get_absolute_url())

だから、form_validメソッドのオーバーライドはうまくいきましたが、それがどのように行われるべきだとは思いませんか? このアクションを配置するためのより良い場所はありますか? これを行う従来の方法は何ですか?

4

4 に答える 4

3

これを行うもう 1 つの方法は、保存動作をフォーム自体に配置することです。

class NewPostForm(forms.ModelForm):
    class Meta:
        model = BlogPost
        fields = ('title', 'post_body')

    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user')
        super(NewPostForm, self).__init__(*args, **kwargs)

    def save(self):
        obj = super(NewPostForm, self).save(commit=False)
        obj.user = self.user
        obj.pub_date = timezone.now()
        obj.save()
        return obj

これにより、ビューの外でより再利用可能な方法でロジックがうまくカプセル化されます。

ビューをオーバーライドget_form_kwargsしてユーザーを渡すか、フォームを初期化するときにビューによって確実に渡されるようにするためにUserFormKwargsMixinクラスを使用する必要があります。django-bracesuser

をオーバーライドする代わりに、フォームで使用できるdjango-bracesも提供することに注意してください。中括弧のアプローチを取ると、次のようになります。UserKwargModelFormMixin__init__()

フォーム.py :

class NewPostForm(UserKwargModelFormMixin, forms.ModelForm):
    class Meta:
        model = BlogPost
        fields = ('title', 'post_body')

    def save(self):
        obj = super(NewPostForm, self).save(commit=False)
        obj.user = self.user
        obj.pub_date = timezone.now()
        obj.save()
        return obj

views.py :

class NewPostView(UserFormKwargsMixin, generic.edit.CreateView):
    model = BlogPost
    form_class = NewPostForm
于 2013-09-27T13:35:35.493 に答える