day = get_object_or_404(Day, pk=pk)
The subsequent processing is the same flow as the add function.This is the output page of the result of learning about Django on Udemy. The previous article is here .
This time, I'd like to create a super-simple diary application in Django. Also, this time, in order to deepen the understanding of how Django works, we will not use the class-based general-purpose view, but only create it with functions.
top page
Details page
Update page
Delete page
First of all, from the environment construction. Create a project called Second and a Django app called diary. The project name is arbitrary, but it is safer to use only half-width alphanumeric characters if possible. If there are underscores or blank spaces in the project name, a mysterious error may occur in the procedure described below.
django-admin startproject Second
cd diary_project
py .\manage.py startapp diary
Register the diary app in settings.py and set Japan time
Second\Second\sattings.py
INSTALLED_APPS = [
'diary',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'
models.py This time, the process of registering data in Django's DB will occur, so define what kind of data will be put in the DB in models.py. Conversely, if you look at models.py, you can see what data fields are available in Django's DB. Also, if you do not explicitly set a primary key in models.py, a primary key called id will be set automatically.
Second\Second\models.py
from django.db import models
from django.utils import timezone
class Day(models.Model):
#I haven't declared it here, but the primary key called id is automatically registered.
title = models.CharField('title', max_length=200)
text = models.TextField('Text')
date = models.DateField('date', default=timezone.now)
After inputting models.py, register it in the DB with manage.py. Move to the folder where manage.py is saved and register it with the following command.
py .\manage.py makemigrations
py .\manage.py migrate
When you run makemigrations, you may get a RecursionError.
RecursionError: maximum recursion depth exceeded while calling a Python object
One of the causes of the error is that the project name contains characters other than half-width alphanumeric characters. This can happen if the path contains blank spaces. Please note that blank spaces may be included in the path if saved in a special folder such as OneDirve.
urls.py In urls.py directly under the project, set to go to urls.py directly under the app.
Second\Second\urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('diary/', include('diary.urls')),
]
Enter urls.py directly under the app as follows.
Second\diary\urls.py
from django.urls import path
from . import views
app_name = 'diary'
urlpatterns = [
path('', views.index, name='index'), #List page
path('add/', views.add, name='add'), #Additional page
path('update/<int:pk>/', views.update, name='update'), #Update page
path('delete/<int:pk>', views.delete, name='delete'), #Delete page
path('detail/<int:pk>', views.detail, name='detail'), #Details page
]
Register the URL in urls.py directly under the app.
This time, we will create 5 pages of list, add, update, delete, and details.
<int: pk>
means the primary key associated with each article.
When I explained models.py, I wrote that the primary key called id was automatically registered, but
In Django, it's customary to represent that id with a variable called pk.
You can express it as <int: id>
, but let's say <int: pk>
.
For example, to access the detail page where pk is 1, it would be diary / detail / 1 /
.
Not required for list pages or additional pages that are not tied to a particular article.
forms.py Before creating views.py, create a new file called forms.py. Create a file called forms.py in the same folder as views.py (Second \ diary) Please make the contents as follows.
Second\diary\forms.py
from django import forms
from .models import Day
class DayCreateForm(forms.ModelForm):
class Meta:
model = Day
fields = '__all__'
Of course, when creating or updating an article, an input field is required in the HTML file. In order to create the input field, it is necessary to configure a Form in the HTML file.
It is this forms.py that defines what data to pass to that Form.
This time, let's pass all the data of the Day class defined in models.py.
If you want to pass everything, set fields ='__ all__'
.
The class name DayCreateForm is arbitrary, The class Meta in it is a fixed phrase. Let's not change it.
views.py Create a function to display the list, add, update, delete, and detail pages in views.py. Originally, it's easy to write by using Django's divine feature called class-based generic views. Since this article is about writing with a function, I dare to write it with a function.
Second\diary\views.py
from django.shortcuts import render, redirect, get_object_or_404
from .forms import DayCreateForm
from .models import Day
def index(request):
"""
Display a list of diary
"""
context = {
'day_list':Day.objects.all(),
}
return render(request, 'diary/day_index.html', context)
def add(request):
"""
Added diary article
"""
#Create a form based on the submitted content. If not POST, create an empty form.
form = DayCreateForm(request.POST or None)
# method==POST is when the send button is pressed. form.is_valid is True if there is no problem with the input contents.
if request.method == 'POST' and form.is_valid():
form.save()
return redirect('diary:index')
#If there is an error in the normal access or input contents, day again_form.Show html
context = {
'form':form
}
return render(request, 'diary/day_form.html', context)
def update(request, pk):
"""
Change diary article
"""
#Get Day based on url pk (pk is the same as id)
day = get_object_or_404(Day, pk=pk)
#Associate the acquired Day with the form
form = DayCreateForm(request.POST or None, instance=day)
# method=POST(Press the send button), And if there is no problem with the input contents, save the form.
if request.method == 'POST' and form.is_valid():
form.save()
return redirect('diary:index')
#Display the first page if there is a problem with normal access or input contents
context = {
'form':form
}
return render(request, 'diary/day_form.html', context)
def delete(request, pk):
"""
Delete diary article
"""
#Get Day based on the PK of the URL (pk is the same as id)
day = get_object_or_404(Day, pk=pk)
# method=POST(Press the send button)
if request.method == 'POST':
day.delete()
return redirect('diary:index')
#Normal access. Or access if there is a problem.
context = {
'day':day
}
return render(request, 'diary/day_delete.html', context)
def detail(request, pk):
"""
Diary detail page
"""
#Get Day based on URL PK
day = get_object_or_404(Day, pk=pk)
context = {
'day':day
}
return render(request, 'diary/day_detail.html', context)
def index (request):
is a function to display a list of articles.
Assign all the data of Day class in models.py to context.
Using the render function, I am passing the created context to day_index.html.
def add (request):
is a function for creating a new article.
Create a form based on the submitted contents with form = DayCreateForm (request.POST or None)
. If it is in the state before submission, it will be an empty form.
`ʻif request.method =='POST' and form.is_valid (): `` is the process when the submit button is pressed and there is no problem with the contents.
Since there is no problem, save it with form.save () and redirect to the index.html page.
In case of normal access or if there is an error in the input, pass the context to day_form.html with the render function.
def update (request, pk):
is a function to change the content of the article.
When viewing this update page, the URL will be diary / update / day = get_object_or_404(Day, pk=pk)
The subsequent processing is the same flow as the add function.
def delete (request, pk):
is a function to delete an article.
It is almost the same process as update, but since it is deleted, there is no need to operate the form, so it is not created.
Delete the article with day.delete () and redirect to index.html.
def detail (request, pk):
is a function to display the detail page of the article.
It's simple because you don't have to create a form either.
Finally, create an html file. Create a templates folder under the diary folder, and then create a diary folder.
First, create base.html. This is the html file that is the masterpiece of everything.
Link the list page and new article creation in the nav part.
Link with {% url'<app name>: <name value defined in urls.py>'%}
.
Second\diary\templates\diary\base.html
<!doctype html>
<html lang="ja">
<head>
<title>Diary application</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
</head>
<body>
<div class="container">
<nav class="nav">
<a class="nav-link active" href="{% url 'diary:index' %}">List</a>
<a class="nav-link" href="{% url 'diary:add' %}">add to</a>
</nav>
{% block content %}
{% endblock %}
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<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.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
</body>
</html>
It is a list page of articles.
From views.py, day_list is passed the context of Key, so You can use day_list to access the article titles and dates stored in the DB. This is displayed using a for statement.
It is a mechanism to access the update page of each article by passing day.pk to update and delete.
Second\diary\templates\diary\day_index.html
{% extends 'diary/base.html' %}
{% block content %}
<h1>Diary list</h1>
<table class="table">
<thead>
<tr>
<th>title</th>
<th>date</th>
<th>Update process</th>
<th>Delete process</th>
</tr>
</thead>
<tbody>
{% for day in day_list %}
<tr>
<td><a href="{% url 'diary:detail' day.pk %}">{{ day.title }}</a></td>
<td>{{ day.date }}</td>
<td><a href="{% url 'diary:update' day.pk %}">update</a></td>
<td><a href="{% url 'diary:delete' day.pk %}">Delete</a></td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
This is the details page. The title, text and date are displayed. After the text, the line breaksbr is added This is to express line breaks on HTML. There is no problem without it.
Second\diary\templates\diary\day_detail.html.html
{% extends 'diary/base.html' %}
{% block content %}
<table class="table">
<tr>
<th>title</th>
<td>{{ day.title }}</td>
</tr>
<tr>
<th>Text</th>
<td>{{ day.text | linebreaksbr}}</td>
</tr>
<tr>
<th>date</th>
<td>{{ day.date }}</td>
</tr>
</table>
<a href="{% url 'diary:update' day.pk %}"><button class="btn btn-primary">update</button></a>
<a href="{% url 'diary:delete' day.pk %}"><button class="btn btn-danger">Delete</button></a>
{% endblock %}
Creating a form. It is used for creating and updating articles.
Second\diary\templates\diary\day_form.html
{% extends 'diary/base.html' %}
{% block content %}
<form action="" method="POST">
<table class="tabel">
<tr>
<th>title</th>
<td>{{ form.title }}</td>
</tr>
<tr>
<th>Text</th>
<td>{{ form.text }}</td>
</tr>
<tr>
<th>date</th>
<td>{{ form.date }}</td>
</tr>
</table>
<button type="submit" class="btn btn-primary">Send</button>
{% csrf_token %}
</form>
{% endblock %}
Similar content continues, but this is the end. The last is the delete page.
Second\diary\templates\diary\day_delete.html
{% extends 'diary/base.html' %}
{% block content %}
<form action="" method="POST">
<table class="table">
<tr>
<th>title</th>
<td>{{ day.title }}</td>
</tr>
<tr>
<th>Text</th>
<td>{{ day.text }}</td>
</tr>
<tr>
<th>date</th>
<td>{{ day.date }}</td>
</tr>
</table>
<p>Delete this data.</p>
<button type="submit" class="btn btn-primary">Delete</button>
{% csrf_token %}
</form>
{% endblock %}
After that, let's check the operation with py manage.py run server. If you can create / update / delete an article, you are successful.
Recommended Posts