web-dev-qa-db-ja.com

Djangoフォームの追加に基づいてフォームを編集しますか?

Niceフォームを作成し、それを処理するための大きく複雑な「追加」機能を作成しました。このように始まります...

_def add(req):
    if req.method == 'POST':
        form = ArticleForm(req.POST)
        if form.is_valid():
            article = form.save(commit=False)
            article.author = req.user
            # more processing ...
_

edit()メソッドでその機能をすべて複製したくないので、editはまったく同じテンプレートを使用でき、idadd関数がフォームの編集内容を認識できるようにするためのフィールド。しかし、これにはいくつかの問題があります

  1. add funcの_article.id_はどこに設定しますか?それは_form.save_の後でなければなりません。それは記事が作成される場所だからです。しかし、フォームが一意の制約のために無効であるため(ユーザーがすべてを編集しない限り)それに到達することさえありません。 _is_valid_チェックを削除するだけですが、_form.save_は代わりに失敗します。
  2. 実際にフォームがis無効である場合、編集機能で動的に追加したフィールドは保持されません。

それで、どうすればこれに対処できますか?

44
mpen

ModelFormからフォームを拡張する場合は、instanceキーワード引数を使用します。ここでは、既存の記事を編集または追加するかどうかに応じて、既存のinstanceまたは新しいものを渡します。どちらの場合も、authorフィールドがインスタンスに設定されているため、commit=False 必須ではありません。また、著者だけが自分の記事を編集できると想定しているため、HttpResponseForbidden応答であることに注意してください。

from Django.http import HttpResponseForbidden
from Django.shortcuts import get_object_or_404, redirect, render, reverse


@login_required
def edit(request, id=None, template_name='article_edit_template.html'):
    if id:
        article = get_object_or_404(Article, pk=id)
        if article.author != request.user:
            return HttpResponseForbidden()
    else:
        article = Article(author=request.user)

    form = ArticleForm(request.POST or None, instance=article)
    if request.POST and form.is_valid():
        form.save()

        # Save was successful, so redirect to another page
        redirect_url = reverse(article_save_success)
        return redirect(redirect_url)

    return render(request, template_name, {
        'form': form
    })

そしてあなたのurls.py

(r'^article/new/$', views.edit, {}, 'article_new'),
(r'^article/edit/(?P<id>\d+)/$', views.edit, {}, 'article_edit'),

同じeditビューが追加と編集の両方に使用されますが、編集URLパターンのみがビューにidを渡します。これをフォームで適切に機能させるには、フォームからauthorフィールドを省略する必要があります。

class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        exclude = ('author',)
100
Daniel Naab

フォームに非表示のIDフィールドを設定できます。編集フォームの場合、追加フォームのフォームと共に渡され、req.POSTで設定できます。

formData =  req.POST.copy()
formData['id'] = getNewID()

そしてそのformDataをformに渡します

2
Anurag Uniyal