Форма редактирования Django на основе формы добавления?

Я сделал приятную форму и большую сложную функцию "добавить" для ее обработки. Он начинается так...

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 может использовать тот же самый шаблон и, возможно, просто добавит в форму поле id, чтобы < Функция t24 > знала, что она редактирует. Но есть пара проблем с этим

  • Где бы я установил article.id в функции add? Это должно быть после form.save, потому что там, где создается статья, но она никогда не достигла бы этого, потому что форма недействительна из-за уникальных ограничений (если пользователь не отредактировал все). Я могу просто удалить проверку is_valid, но вместо этого произойдет сбой form.save.
  • Если форма фактически недействительна, поле I, динамически добавленное в функцию редактирования, не сохраняется.

Итак, как мне с этим справиться?

Ответ 1

Если вы расширяете форму из ModelForm, используйте аргумент ключевого слова instance. Здесь мы передаем либо существующий instance, либо новый, в зависимости от того, редактируем ли мы или добавляем существующую статью. В обоих случаях в экземпляре задается поле author, поэтому commit=False не требуется. Также обратите внимание, что я предполагаю, что автор может редактировать свои собственные статьи, следовательно, HttpResponseForbidden response.

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-адреса редактирования передает идентификатор в представление. Чтобы сделать эту работу хорошо с вашей формой, вам нужно опустить поле author из формы:

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

Ответ 2

У вас может быть скрытое поле идентификатора в форме и для формы редактирования он будет передан с формой для добавления формы, которую вы можете установить в req.POST, например.

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

и передать эту форму Data для формирования