3

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?

2
  • why both edit view and delete view has same name? Commented Dec 29, 2019 at 4:29
  • Since i while updating the object, a new instance is created again with values that queried. So i deleted the previous object so that only the new object stays in the database!! Commented Dec 29, 2019 at 4:32

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

Actually, by changing the return redirect('editpost') after the form is saved is where i went wrong. By changing the redirect url, it works fine with the previous code. However, the action tip you gave, reduced replicating the same template. Thank you so much!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.