Это правильный способ открыть объект из БД для редактирования в той же форме, а затем сохранить обновленное значение для того же объекта с помощью django?

#python #django #django-forms

#python #django #django-forms

Вопрос:

Это мой код:

Чтобы создать новый объект issue, используйте form

 def raise_issue_view(request, *args, **kwargs):
    
    form = RaiseIssueForm(request.POST or None)
    if form.is_valid():
        form.save()

        obj = RaiseIssueModel.objects.latest('id')
        return redirect("/raise_issue/"   str(obj.id))
    
    context = {
        "form" : form
    }

    return render(request,"raise_issue.html", context)
  

Чтобы отредактировать ранее созданную проблему, по ссылке 127 …8000/edit_issue/<issue_id>

 def edit_issue_view(request, id):
    obj = RaiseIssueModel.objects.get(id=id)

    form = RaiseIssueForm(instance=obj)
    new_form = RaiseIssueForm(request.POST, instance=obj)
    

    if new_form.is_valid():
        
        new_form.save()
        
        return redirect("/raise_issue/"   str(obj.id))
    
    context = {
        "form" : form
    }

    return render(request,"raise_issue.html", context)
  

Здесь, в режиме редактирования вопроса, сначала я загружаю данные БД в «форму», затем я создаю новую форму (new_form) для сохранения обновленных данных.
Это нормально, или есть лучший способ сделать это?
Спасибо,

Ответ №1:

Это работает, но неверно… Проверенной формой является new_form . Если оно неверно, вы отобразите ошибки из формы (в которой нет ошибок, поскольку она не была отправлена).

Вы также не смогли проверить, существует ли объект.

 def edit_issue_view(request, id):
    try:
        obj = RaiseIssueModel.objects.get(id=id)
    except RaiseIssueModel.DoesNotExist:
        raise Http404()

    form = RaiseIssueForm(request.POST or None, instance=obj)
    
    if form.is_valid():
        form.save()
        
        return redirect("/raise_issue/"   str(obj.id))
    
    context = {
        "form" : form
    }

    return render(request,"raise_issue.html", context)
  

Затем для вашей первой формы. Метод save() вашей формы должен возвращать созданный объект (при условии, что вы использовали django.forms.ModelForm). Итак, вы можете написать это так:

 def raise_issue_view(request, *args, **kwargs):
    
    form = RaiseIssueForm(request.POST or None)
    if form.is_valid():
        obj = form.save()
        return redirect("/raise_issue/"   str(obj.id))
    
    context = {
        "form" : form
    }

    return render(request,"raise_issue.html", context)
  

Комментарии:

1. Это отлично работает! Я пробовал form = RaiseIssueForm(request.POST, instance=obj) раньше, и это не работало, но после добавления «или нет` к этому, он работает нормально. Это намного чище, и спасибо за объяснение недостатков в моем коде.

Ответ №2:

Вы можете использовать GET и POST запросы для выполнения разных функций. GET для извлечения объекта из БД и POST для внесения изменений и сохранения его в БД. Например:

 from django.shortcuts import get_object_or_404

def edit_issue_view(request, id):
    obj = get_object_or_404(RaiseIssueModel, pk=id)
    new_form = RaiseIssueForm(request.POST or None, instance=obj)
    if request.method == 'POST':
        if new_form.is_valid(): 
            new_form.save() 
            return redirect("/raise_issue/"   str(obj.id))
    
    context = {
        "form" : new_form
    }

    return render(request,"raise_issue.html", context)
  

Также добавьте незначительное изменение в raise_issue_view методе, касающееся перенаправления в режим редактирования. Как вы можете видеть, form.save() возвращает объект, который вы только что создали / обновили. Вы можете использовать это для перенаправления:

 if form.is_valid():
    obj = form.save()
    return redirect("/raise_issue/"   str(obj.id))
  

Наконец, для перенаправления лучше использовать именованные URL-адреса. Например, если ваш URL выглядит следующим образом:

 path('raise_issue/<int:pk>/', name='raise_issue')
  

Затем вы можете использовать следующий код для перенаправления:

 return redirect('raise_issue', pk=obj.pk)
  

Для получения дополнительной информации, пожалуйста, обратитесь к документации.

Комментарии:

1. Спасибо за ваш ответ, это тоже работает, и да, я изменил свой код, чтобы включить obj = form.save() это намного чище, я буду читать дальше redirect