[PYTHON] Django beginners create simple apps 5

Introduction

A continuation of 4 where Django beginners create simple apps. The purpose is to get rid of complicated and troublesome things as much as possible, create a simplified web application, and learn how Django works. Only understand what is connected and how it moves around the back end. Implement CRUD (Create, Read, Update, Delete) and if it works, you will reach the goal. Last time, I rewrote Class-based-view to Function-view and compared the two to see how Django works. This time I would like to implement the Update part and Delete part of CRUD. So, in fact, it's complete.

A series for beginners to create simple apps

-Django Beginners Create Easy Apps 1 --Preparation-Overview of Django-Creating models.py -Django beginners make simple apps 2 --Implementation of Read part (creation of urls.py, views.py, template file) -Django beginners make simple apps 3 --Implementation of Create part (creation of form.py etc.) --Django Beginners make simple apps 4 --Comparison of Class-based-view and Function-view --Django Beginners Create Easy Apps 5 (Completed This Time) --Implementation of Update part and Delete part

environment

Ubuntu 20.04 LTS Python 3.8.2 Django 3.02

Premise

The project name is config and the app name is myapp. In other words, the following two commands have been executed


(myenv)$ django-admin startproject config .
(myenv)$ python manage.py startapp myapp

The templates directory is created in the same hierarchy as manage.py, and setting.py has also been modified. (See "Django Beginners Create Easy Apps 1)

1. Implementation of Update part

Rough image

The log is displayed on the page of the movie details screen, and when you want to edit the log for a while, you can edit it by pressing the button.

5FF00F76-C9CC-4796-B073-754EAA3173C2.jpeg

When creating a new page, create it in the order of urls.py → views.py → template. I think that the omission of thinking will be reduced by fitting the method of making into a mold in this way. First, write the address ʻupdate / log / <int: pk> /` when updating the log (impression) in urls.py.

urls.py (update part)

myapp/urls.py


from django.urls import path, include
from myapp import views

app_name = 'myapp'
urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
    path('movie/<int:pk>/', views.MovieDetailView.as_view(), name='movie_detail'),
    # (Omission)
    path('update/log/<int:pk>/', views.UpdateLogView.as_view(), name='updatelog'), #Add this line
]

views.py (update part)

Next, write the code of UpdateLogView which is Class-based-view in views.py.

myapp/views.py



class UpdateLogView(generic.UpdateView):
    model = Log
    form_class = LogForm
    template_name = "myapp/register.html"
    def get_success_url(self):
        return reverse('myapp:movie_detail', kwargs={'pk': self.object.movie.pk })

#If Function-If you write in view, it is as follows

def updatelog(request, pk):
    obj = get_object_or_404(Log, id=pk)
    if request.method == "POST":
        form = LogForm(request.POST, instance=obj)
        if form.is_valid():
            form.save()
            return redirect('myapp:movie_detail', pk=obj.movie.pk)
    else:
        form = LogForm(instance=obj)
        return render(request, 'myapp/register.html', {'form': form})

Four items should be specified in Class UpdateLogView (same as the previous CreateView).

  1. What model to use
  2. What to use for form
  3. What template to use
  4. Where to fly if successful

So, you can see how it actually works with the def update log in Function-view. The request part of (request, pk) is an HttpRequest object that can be created by pressing the edit button in detail.html. The id number of the log is entered in the pk part. Then, using this pk, a number is entered in the <int: pk> part of ʻupdate / log / <int: pk> /` in urls.py. Note below.

F87D58D8-8228-4E22-AB65-5682ABBC5233.jpeg

This completes the Update implementation. Next, implement the Delete part.

2. Implementation of Delete part

Rough image

I want two functions, one to erase the log (impression) and the other to erase the movie data. Then you should write two sets of code in urls.py and two in views.py.

urls.py (delete part)

myapp/urls.py



from django.urls import path, include
from myapp import views

app_name = 'myapp'
urlpatterns = [
    path('', views.index, name='index'),
    # (Omission)
    path('delete/log/<int:pk>/', views.deletelog, name='deletelog'), #Add this line
    path('delete/movie/<int:pk>/', views.deletemovie, name='deletemovie'), #Add this line
]

The address described here is the confirmation screen for deletion. The place where "Can I erase this?" Next, write the code in views.py.

views.py (the part that erases the impression)

myapp/views.py



class DeleteLogView(generic.DeleteView):
    model = Log
    def get_success_url(self):
        return reverse('myapp:movie_detail', kwargs={'pk': self.object.movie.pk })

#Function from here-view

def deletelog(request, pk):
    obj = get_object_or_404(Log, id=pk)
    movie_id = obj.movie.pk
    if request.method =="POST": 
        obj.delete() 
        return redirect('myapp:movie_detail', pk=movie_id)
    context = {'obj':obj}
    return render(request, "myapp/delete.html", context)

In Class-based-view, all you have to do is specify the model and the page to skip when it succeeds. However, if there are only these two items, the name of the deletion confirmation page needs to be "○○ _confirm_delete.html". The name of the model is entered in 〇〇. This time it will be "log_confirm_delete.html". In Function-view, "delete.html" was created and used as a deletion confirmation page.

Class-based-view does it automatically, and what I had to devise in Function-view is that after deleting the log, the details screen after deletion is displayed. If you don't save the movie id of the log before clearing the log, you won't be able to return to the movie details screen. Note below.

51EECC10-5523-49E7-A77E-1ACD0A0D133B.jpeg

views.py (the part that erases movie data)

myapp/views.py



class DeleteMovieView(generic.DeleteView):
    model = Movie
    def get_success_url(self):
        return reverse('myapp:index')

#Function from here-view

def deletemovie(request, pk):
    obj = get_object_or_404(Movie, id=pk)
    if request.method == "POST":
        obj.delete()
        return redirect('myapp:index')
    context = {'obj':obj}
    return render(request, "myapp/delete.html", context)

The code is almost a repeat of delete log. The only difference is that it jumps to the index after deletion.

Write the template part

This template is the deletion confirmation screen (delete.html). The same delete.html can be used regardless of whether the log is deleted or the movie data is deleted. Although the display looks awkward (one of the top and bottom is blank).

myapp/templates/myapp/delete.html


<form method="POST">
    {% csrf_token %}
    {{obj.movie}}<br> #This is displayed when deleting the log
    {{obj.text}}<br>
------------------------------<br>
    {{obj.title}}<br> #This is displayed when you delete the movie
    {{obj.director}}<br>
    Do you want to delete it?<br>
    <button type="submit">OK</button>
</form>

Add edit and delete buttons to detail.html with

templates/myapp/detail.html


{% for log in movie.log.all %}
    <li>
        <button onclick="location.href='{% url 'myapp:updatelog' log.id %}'">edit</button>
        <button onclick="location.href='{% url 'myapp:deletelog' log.id %}'">delete</button>
        {{ log.text }}
    </li>

{% endfor %}

This completes the implementation of the Delete part.

Other fine adjustment

--Put a link in index.html to jump to each page

index.html


<a href="{% url 'myapp:registerdirector' %}">Register Director</a><br>
<a href="{% url 'myapp:registermovie' %}">Register Movie</a><br>
<a href="{% url 'myapp:writinglog' %}">Writing Log</a>

--Add function + link so that you can enter the log of the movie from detail.html

views.py


def writingthismovielog(request, movie_id):
    obj = get_object_or_404(Movie, id=movie_id)
    form = LogForm({'movie':obj})
    if request.method == "POST":
        form = LogForm(request.POST)
        if form.is_valid():
            l = form.save(commit=False)
            l.save()
            return redirect('myapp:movie_detail', pk=l.movie.pk)
    else:
        return render(request, 'myapp/register.html', {'form': form})

When I pressed the button, only the title of the movie was already entered, and I wanted to just write my impressions. The point of ingenuity is form = LogForm ({'movie': obj}). You created an object, specified the title part in a dictionary type, and put it in LogForm. I tried it and it worked. This is because it should be like this! It's fun if it works as I expected. It's just this one line, but I'm really happy about it.

detail.html


<a href="{% url 'myapp:writingthismovielog' movie.id %}">Write log of this movie data</a><br>
<a href="{% url 'myapp:deletemovie' movie.id %}">Delete this movie data</a><br>
<a href="{% url 'myapp:index' %}">To Index</a><br>

Then paste the above link in detail.html and complete the fine adjustment.

It works like this ... Completed! !!

Update and Delete Log Delete Movie data
editdelete.gif deletemovie.gif

For the above gif video, capture the screen as a video with SimpleScreenRecord and convert the video to gif with ffmpeg. It's easy to do and it's out of tune. Isn't the world going too far?

Afterword

Aiming only to work, it doesn't deploy and looks bad, but I was able to implement CRUD (Create, Read, Update, Delete). At least it's working. So, ** Goooooooaaaaallll! ** I was able to hold down the minimum basics. For the first time, this app (Modoki) was an experience with the feeling that "I was able to program on my own!", Which led to a slight confidence that I made 0 to 1. Name this "movielogrecord" and put the code on github. Both ignorance and shame are open to the public. It is https://github.com/soh506/movielogrecord.git. Thank you for reading. We look forward to helping you even a little. Next, let's study around the front end to make it look better. The eternal beginner's study continues ...

Recommended Posts

Django beginners create simple apps 2
Django beginners create simple apps 5
Create a Django schedule
django oscar simple tutorial
Create Django Todo list
Create an API with Django
Create a (simple) REST server
Create ToDo List [Python Django]
Create a homepage with django
Shell to create django project
Create a Django login screen
Create your own Django middleware
Create a simple textlint server
Create and list Django models
(For beginners) Try creating a simple web API with Django
Hello World (beginners) on Django
Create a social integration API for smartphone apps with Django
Rails users try to create a simple blog engine with Django
Steps to create a Django project
Django beginners tried building an environment
[For beginners] Django -Development environment construction-
Create new application use python, django
[Django] Create your own 403, 404, 500 error pages
Create a file uploader with Django