【问题标题】:How to edit an object using model form in django?如何在 django 中使用模型表单编辑对象?
【发布时间】:2020-04-18 08:57:46
【问题描述】:

这可能与this 答案重复。目前,我正在使用与创建对象相同的模型表单来更新对象。

我的views.py 看起来像:(从答案):

def newpost(request):
    form = PostForm(request.POST)
    if request.method == "POST":
        if form.is_valid():
            obj = form.save(commit=False)
            obj.save()
            return redirect('newpost')
    return render(request, 'console/newpost.html', {'form':form})

def editpost(request, pk):
    obj = Post.objects.get(id=pk)
    form = PostForm(instance=obj)
    if request.method == "POST":
        if form.is_valid():
            obj = form.save(commit=False)
            obj.save()
            return redirect('editpost')
    return render(request, 'console/editpost.html', {'form':form})

我在editpost 中的 html 表单看起来像:

<form method="POST" action="{% url 'newpost' %}">
    {% csrf_token %}
    {{form.as_p}}
    <button type="submit"> Submit</button>
</form>

我的urls.py 看起来像:

path('console/post/', c_views.newpost, name='newpost'),
path('console/post/<int:pk>/', c_views.editpost, name='editpost'),

上面的代码工作得很好,但是创建了一个新实例,对象的数据取自pk。

我添加了这样的obj.delete() 代码:

def editpost(request, pk):
    obj = Post.objects.get(id=pk)
    form = PostForm(instance=obj)
    obj.delete()
    if request.method == "POST":
        if form.is_valid():
            obj = form.save(commit=False)
            obj.save()
            return redirect('editpost')
    return render(request, 'console/editpost.html', {'form':form})

这段代码给了我想要的东西,但我知道这不是一个好习惯。我的问题是,这是正确的方法还是我落后于某个地方。 我知道我的editpost html 中的操作不应该是{% url 'newpost' %},但是如果我使用{% url 'editpost' %},我不知道如何在 url 标记内传递 pk 值。谁能建议我正确的方法?

【问题讨论】:

  • 为什么编辑视图和删除视图都同名?
  • 由于我在更新对象时,使用查询的值再次创建了一个新实例。所以我删除了以前的对象,以便只有新对象留在数据库中!!

标签: python django


【解决方案1】:

您的每个视图都应接受 GET 和 POST 方法,当方法为 GET 时,表单被实例化,没有传递给它的 request.POST 数据并且表单只是呈现。

def newpost(request):
    if request.method == 'GET':
        form = PostForm()
    else:  # POST
        form = PostForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('newpost')
    return render(request, 'console/newpost.html', {'form':form})

def editpost(request, pk):
    obj = Post.objects.get(id=pk)
    if request.method == 'GET':
        form = PostForm(instance=obj)
    else:  # POST
        form = PostForm(request.POST, instance=obj)
        if form.is_valid():
            form.save()
            return redirect('editpost')
    return render(request, 'console/editpost.html', {'form':form})

<form method="POST">

如果您没有在表单上设置“action”属性,它会将数据提交到浏览器当前所在的同一 URL。这样您就可以为两个视图使用相同的模板

【讨论】:

  • 实际上,在保存表单后更改return redirect('editpost') 是我出错的地方。通过更改重定向 url,它可以与前面的代码一起正常工作。但是,您提供的action 提示减少了复制相同模板的次数。非常感谢!
猜你喜欢
  • 2020-02-12
  • 2019-02-06
  • 1970-01-01
  • 2011-08-26
  • 2012-12-26
  • 2010-12-29
  • 2016-10-15
  • 2020-04-17
  • 2011-01-24
相关资源
最近更新 更多