This is ** 5th **, a memorandum of making a game record management app for shogi using Django.
The working environment this time is as follows
Also, Django's directory structure looks like this:
- kifu_app_project/
- kifu_app_project/
- __init__.py
- setting.py
- urls.py
- wsgi.py
- kifu_app/
- migrations/
- templates/
- index.html
- __init__.py
- admin.py
- apps.py
- models.py
- tests.py
- urls.py
- views.py
- manage.py
- .gitignore
--Read data from DB to View and display list with Template --Transition from list screen to detail screen for each data --Try using a convenient function for creating a view (generic)
First, let's register some data in the DB.
Then, take out the data with View and display it with Template. Here, the data is fetched from the Information table and displayed in a list.
Create a new URL for ʻinformationList` in urls.py.
kifu_app/urls.py
from django.urls import path
from . import views
app_name = 'kifu_app'
urlpatterns = [
path('', views.index, name='index'),
path('informationList', views.informationList, name='informationList'), #add to
]
Modify views.py as follows and add the informationList method.
views.py
from django.shortcuts import render
from .models import Information #add to(Allows you to work with the Information table)
#~ Omitted ~
def informationList(request):
data = Information.objects.all()
return render(request, 'informationList.html', {'data': data})
The important part is ʻInformation.objects.all ()`. Data is fetched from the Information table in this part. Here, all the data is fetched by the all method.
You can also pick and sort the ones that meet your specific criteria by choosing the right method. The following people have summarized it, so I think it will be helpful. [Summary of Django database operations] 1
Next, let's create informationList.html and display the data passed from View for the time being.
informationList.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Kifu APP</title>
</head>
<body>
<h3>{{ data }}</h3>
</body>
</html>
Then you will see something like the following on the screen.
Next, let's turn the data with for and extract it one by one.
informationList.html
<body>
{% for each_data in data %}
<h3>{{ each_data }}</h3>
{% endfor %}
</body>
With this, I feel that I can only retrieve the game date and time.
However, this is because when I added the \ _ \ _ str__ method to the Information class of models.py in Part 3, it returned self.date, so I think that it is actually good to recognize it as Object.
So, let's retrieve the individual data held in the Object.
To access individual data, connect the column variables defined in models.py with the. Operator.
informationList.html
<body>
{% for each_data in data %}
<h3>{{ each_data }}</h3>
<table border="1">
<tr>
<td>{{ each_data.date }}</td>
<td>{{ each_data.sente }}</td>
<td>{{ each_data.gote }}</td>
<td>{{ each_data.small_class }}</td>
</tr>
</table>
{% endfor %}
</body>
I was able to display the individual data properly!
Next, you can move to each detail page from the list screen.
It is not realistic to create an HTML file for each data when trying to create a detail page. It is common to prepare a template for the detail screen and change the displayed value according to the selected data.
What you need to do at that time is that ** you have to send the information about which data was selected from the Template (list screen) to View **. Without this, the View wouldn't know which detailed data to pass to the Template (details screen).
A common practice is to put the information in the URL.
For example, let's put the ID of the data in the URL. Then, if the URL is / informationDetail / 2
, you can judge from View that you should fetch the data with ID = 2.
Now, let's implement such a function.
First, create a URL. However, unlike before, the part where the ID is placed is not a fixed value but a variable value, so write it in an acceptable way. Specifically, it is as follows.
kifu_app/urls.py
urlpatterns = [
path('', views.index, name='index'),
path('informationList', views.informationList, name='informationList'),
path('informationDetail/<int:information_id>', views.informationDetail, name='informationDetail'),
]
The part you want to make a variable value is OK if you describe the URL in the form of <type: variable name>
.
(Very easy!)
Then the View looks like below.
views.py
from django.shortcuts import render
from .models import Information
from django.shortcuts import get_object_or_404 #add to
#~ Omitted ~
def informationDetail(request, information_id):
detail = get_object_or_404(Information, pk=information_id)
return render(request, 'informationDetail.html', {'detail': detail})
Since the variable name was set to ʻinformation_id in the URL setting earlier, add ʻinformation_id
to the argument of the method to be called.
Please note that an error will occur if this variable name is different from the one written in the URL.
There is also a new method called get_object_or_404
, which is
try:
detail = Information.objects.get(pk=information_id)
except Information.DoesNotExist:
raise Http404("Information does not exist")
It is OK if you recognize that the work of is written in one line.
Simply do the following:
informationDetail.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Kifu APP</title>
</head>
<body>
<h3>{{ detail }}</h3>
<table border="1">
<tr>
<td>{{ detail.id }}</td>
<td>{{ detail.date }}</td>
<td>{{ detail.sente }}</td>
<td>{{ detail.gote }}</td>
<td>{{ detail.result }}</td>
<td>{{ detail.my_result }}</td>
<td>{{ detail.small_class }}</td>
<td>{{ detail.created_at }}</td>
<td>{{ detail.updated_at }}</td>
</tr>
</table>
</body>
</html>
Finally, create a link in informationList.html so that you can transition to informationDetail.html.
To create a link, Template uses the a tag as well as HTML, but the problem is how to specify the destination in the href attribute. As the project grows in the future, the directory structure may change. In such a case, if the href attribute is specified as a relative path, the path must be rewritten one by one, which is very troublesome.
So, in Django, you don't write a specific path, but use the "URL name" to specify the destination. Specifically, it is as follows.
informationList.html
<td><a href="{% url 'kifu_app:informationDetail' %}">{{ each_data.date }}</a></td>
After enclosing it in {%%}
, write ʻurl`.
Next, when creating a URL in urls.py, describe the URL name * specified in the * name attribute together with the app_name of that urls.py.
In other words, "follow the path of the URL Conf named informationDetail in the URLConf named kifu_app".
Furthermore, this time I want to pass a value to the path, which is written as follows.
informationList.html
<td><a href="{% url 'kifu_app:informationDetail' each_data.id %}">{{ each_data.date }}</a></td>
This will pass the value of each_data.id to the specified URL!
When I actually check it ... If you click the link further ... It worked!
So far, I have implemented the List and Detail functions, but since I often use this function when creating a project, Django has made it so that the View part can be easily implemented.
For details, the following people are very easy to understand and write in detail, so please refer to it.
[Introduction to class-based generic views in Django and sample usage] 2
[Split Template] 3