Reputation: 77
This may possibly be a duplicate of this answer. Currently, i'm working on updating an object using the same model form that is used to create the object.
my views.py
looks like: (as from the answer):
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})
And my html form in editpost
looks like:
<form method="POST" action="{% url 'newpost' %}">
{% csrf_token %}
{{form.as_p}}
<button type="submit"> Submit</button>
</form>
and my urls.py
looks like:
path('console/post/', c_views.newpost, name='newpost'),
path('console/post/<int:pk>/', c_views.editpost, name='editpost'),
And the above codes works perfectly fine, but creates a new instance, with the data of the object taken from pk.
I added a obj.delete()
code like this:
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})
This code gives me the exact thing i wanted, but i know it's not a good practice. My question here is, is this a correct way or am i lagging somewhere.
I know the action in my editpost
html should not be {% url 'newpost' %}
, but if i use {% url 'editpost' %}
i don't know how to pass the pk value inside the url tag. Can anyone suggest me the correct way?
Upvotes: 3
Views: 1893
Reputation: 32244
Each of your views should accept GET and POST methods, when the method is GET the form is instantiated with no request.POST
data passed to it and the form is just rendered.
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">
If you do not set the "action" attribute on a form it will submit the data to the same URL that the browser is currently on. This way you can use the same template for both views
Upvotes: 1