🔖 Day18 - Django views for editing and deleting a post

2018 - 06 - 26
🔖 Day18 - Django views for editing and deleting a post
0. [TL:DR] To submit a new post or comment we can provide a blank form and bind it to request.POST, such as form = PostForm(request.POST) in views.py. If we want to edit an existing post or comment, we'd rather see a pre-filled form instead. To do so we need to call the instance.
1. [views function for editing] In this demo, we are going to edit an existing post from Models: Post, via exisiting form Form: PostForm which is also used for submitting new posts. To edit a post:
from .models import Post
from .forms import PostForm
from django.urls import reverse

def edit_post(request, key):
    post = Post.objects.get(pk=key)
    if request.method == 'POST':
        form = PostForm(request.POST, instance=post)
        if form.is_valid():
            form.save()
            url = reverse('postpage', kwargs={'key': key})
            return render(request, 'edit_done.html', {'url': url})
        else:
            form = PostForm(instance=post)
    else:
        form = PostForm(instance=post)
    return render(request, 'edit.html', {'form':form, 'post':post})

In the snippet above, we called instance=post such that the form is pre-filled already upon page visiting. After form.save() you may head back to the post page directly, however if you have a comment form on the same post page, the rendering may try to submit the comment form at the same time due to request.POST. So it is better to render a dummy page edit_done.html after saving the form. By using django.urls.reverse, we can instruct the template to redirect to the original post page url via request.GET method. We will work on the templates later.
2. [views function for deleting] To delete a post, we use the objects method .delete(), the function is simple:
def del_post(request, key):
    post = Post.objects.get(pk=key)
    post.delete()
    return render(request, 'del_done.html')

Similary, a dummy template del_done.html for redirecting is needed.
3. [template for redirecting] As mentioned in the end of Part 1, we need dummy templates (i.e. edit_done.html, del_done.html) which redirect to the post page after successfully updated a post.
<head>
    <meta http-equiv="refresh" content="3; url={{url}}">
</head>

<div align='center'>
    <p>Post Updated Successfully</p>
    <p>Redirecting to the post</p>
</div>

From the views function edit_post in Part 1, the parameter url is passed to this template. Note that the {{url}} should be changed into other page such as index for del_done.html. Through http-equiv='refresh', this dummy page will redirect to the post page in 3 seconds as assigned.
4. [template for the form] Now we are going to create a template for editing the post, i.e. edit.html. To ensure not clicking delete button by mistakes, it is better to build a pop-up dialogue for confirmation. Here I am using Bootstrap to do so:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

<div class='modal' id='delModal'>
    <div class='modal-dialog'>
        <div class='modal-content'>
            <div class='modal-body bg-danger text-white'>
                Delete this post?
            </div>
            <div class='modal-footer'>
                <button type='button' data-dismiss='modal'>Cancel</button>
                <a href='{% url "delete" key=post.pk %}'>
                    <button type='button'>Delete</button>
                </a>
            </div>
        </div>
    </div>
</div>

<div>
    <form method='POST'>
        {% for field in form %}
        <label for={{field.name}}>{{field.label_tag}}</label>
        {{field}}
        {% endfor %}
        <button type='submit'>Update</button>
        <button type='button' id='delete'>Delete</button>
    </form>
</div>

<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

<script>
    $(document).ready(function(){
        $('#delete').click(function(){
            $('#delModal').modal('show');
        });
    });
</script>

Note how the script is written to faciliate Bootstrap - Modal component.
5. [setting urlspatterns] Finally, we need to define the urlpatterns in urls.py:
from django.urls import path
from blog import views as bv

urlpattersn=[
        ...
        path('edit/', bv.edit_post, name='edit_post'),
        path('delete/', bv.del_post, name='del_post')
    ]

Comments

There is no comment yet

New Comment

Please Login to comment