Практические проекты Django — страницы 183 и 184

#python #django #projects

#python #django #Проекты

Вопрос:

На страницах 183 и 184 есть следующий код :

 def edit_snippet(request, snippet_id):
    snippet = get_object_or_404(Snippet, pk=snippet_id)
    if request.user.id != snippet.author.id:
        return HttpResponseForbidden()
    if request.method == 'POST':
        form = SnippetForm(instance=snippet, data=request.POST)
        if form.is_valid():
            snippet = form.save()
            return HttpResponseRedirect(snippet.get_absolute_url())
    else:
        form = SnippetForm(instance=snippet)
    return render_to_response('cab/snippet_form.html',{ 'form': form, 'add': False })
edit_snippet = login_required(edit_snippet)
  

Почему необходимо добавлять сюда атрибут data :

 form = SnippetForm(instance=snippet, data=request.POST)
  

Разве атрибута instance недостаточно?

Если метод запроса не POST, то это может быть что угодно, но обычно это метод GET. Почему в этом случае нет атрибута data? Почему необходимо учитывать другие методы запроса? Не могли бы мы просто написать :

 def edit_snippet(request, snippet_id):
    snippet = get_object_or_404(Snippet, pk=snippet_id)
    if request.user.id != snippet.author.id:
        return HttpResponseForbidden()
    if request.method == 'POST':
        form = SnippetForm(instance=snippet, data=request.POST)
        if form.is_valid():
            snippet = form.save()
            return HttpResponseRedirect(snippet.get_absolute_url())
    return render_to_response('cab/snippet_form.html',{ 'form': form, 'add': False })
edit_snippet = login_required(edit_snippet)
  

Мне кажется более логичным не разрешать пользователю редактировать свой фрагмент, если метод запроса не POST . Можете ли вы объяснить мне эти моменты?

Ответ №1:

Это способ работы Django: одно и то же представление используется для отображения формы для редактирования (GET), а затем для ее проверки (POST).

Смотрите этот пример в документах:

Стандартный шаблон для обработки формы в представлении выглядит следующим образом:

 def contact(request):
    if request.method == 'POST': # If the form has been submitted...
        form = ContactForm(request.POST) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            # Process the data in form.cleaned_data
            # ...
            return HttpResponseRedirect('/thanks/') # Redirect after POST
    else:
        form = ContactForm() # An unbound form

    return render_to_response('contact.html', {
        'form': form,
    })
  

Ответ №2:

Функция «edit_snippet» обрабатывает как (1) запрос GET для отображения формы для редактирования объекта, так и (2) последующий запрос POST, когда пользователь сохраняет свои изменения в форме.

Имея это в виду, для случая, отличного от POST, имеет смысл просто заполнить форму из переменной «snippet», которая была извлечена из базы данных; как вы заметили, в этом случае параметра «data» нет. То, что было в базе данных, будет отображено пользователю.

Однако, когда пользователь сохраняет форму, в случае POST переменная «snippet» будет содержать только то, что было извлечено из базы данных. Устанавливая параметр «data» для содержимого полей формы (request.POST), которые были опубликованы пользователем, вы разрешаете форме (1) сохранять изменения пользователя из запроса.ОПУБЛИКУЙТЕ в объекте, а затем (2) подтвердите эти изменения.