如何将Django数据库内的数据输出为HTML
你好。我是Class Act基础设施业务部的大塚。
上一次我尝试了在Django中实现登录功能。
以下是那篇文章。
这次我打算使用Django的Models来创建数据库表格,尝试在admin界面中输入数据,以及使数据可以在HTML中输出,即使不通过admin管理界面也可以看到。
目录文件结构
请参考相关网站
我們是根據Django官方教程來創建了投票應用程序以及相關的模型。
● 教程01
https://docs.djangoproject.com/ja/4.2/intro/tutorial01/
● 教程02
https://docs.djangoproject.com/ja/4.2/intro/tutorial02/
环境建设
创建一个问卷调查应用 – 数据库反映和确认
在可以看到manage.py的位置执行以下命令,创建一个名为polls的应用程序。
PS C:\Users\ohtsu\Documents\DjangoEnv\qiita\testPJ> python manage.py startapp polls
PS C:\Users\ohtsu\Documents\DjangoEnv\qiita\testPJ> ls
ディレクトリ: C:\Users\ohtsu\Documents\DjangoEnv\qiita\testPJ
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2023/11/11 16:22 polls
d----- 2023/11/04 20:27 templates
d----- 2023/11/04 20:04 testPJ
-a---- 2023/11/04 20:46 131072 db.sqlite3
-a---- 2023/11/04 20:02 684 manage.py
在创建的polls应用程序的目录中创建一个urls.py文件。
PS C:\Users\ohtsu\Documents\DjangoEnv\qiita\testPJ> cd .\polls\
PS C:\Users\ohtsu\Documents\DjangoEnv\qiita\testPJ\polls> New-Item urls.py
接下来,将对位于项目目录中的settings.py文件进行以下更改。
我认为这是将名为polls的应用程序纳入到项目中的概念。
INSTALLED_APPS = [
"polls", ★追記
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
在应用的models.py文件中,将配置信息设定如下。与官方教程几乎相同。
这样做就是定义要将什么样的数据存入数据库的概念。
# This is polls app models.py
from django.db import models
from django.utils import timezone
import datetime
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField("date published", default=timezone.now)
def __str__(self):
return self.question_text
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
我想要将这个定义应用到sqlite3数据库中。
执行makemigration,然后执行sqlmigrate。最后执行migrate来应用到数据库中。
-
- makemigration:Djangoがデータベースの変更を検出して、それをマイグレーションファイルに記録するために使用される。
-
- sqlmigrate:指定されたマイグレーションファイルに含まれるSQLコードを表示するために使用する。
- migrate:実際にデータベースに反映するために使用する。
首先执行makemigrations。
可以看到检测到了两个变更。还可以看到创建了一个名为0001_initial.py的迁移文件。
PS C:\Users\ohtsu\Documents\DjangoEnv\qiita\testPJ> python manage.py makemigrations polls
Migrations for 'polls':
polls\migrations\0001_initial.py
- Create model Question
- Create model Choice
然后执行sqlmigrate。这将会执行用于迁移的实际SQL命令。
PS C:\Users\ohtsu\Documents\DjangoEnv\qiita\testPJ> python manage.py sqlmigrate polls 0001
BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "question_text" varchar(200) NOT NULL, "pub_date" datetime NOT NULL);
--
-- Create model Choice
--
CREATE TABLE "polls_choice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "choice_text" varchar(200) NOT NULL, "votes" integer NOT NULL, "question_id" bigint NOT NULL REFERENCES "polls_question" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");
COMMIT;
最后我们会进行迁移。
PS C:\Users\ohtsu\Documents\DjangoEnv\qiita\testPJ> python manage.py migrate polls
Operations to perform:
Apply all migrations: polls
Running migrations:
Applying polls.0001_initial... OK
可以通过查看db.sqlite3文件的内容来确认是否进行了这个设置。
使用指定db.sqlite3文件并执行sqlite3命令,可以查看其内容。
PS C:\Users\ohtsu\Documents\DjangoEnv\qiita\testPJ> sqlite3 .\db.sqlite3
SQLite version 3.41.2 2023-03-22 11:56:21
Enter ".help" for usage hints.
sqlite> .tables
auth_group django_admin_log
auth_group_permissions django_content_type
auth_permission django_migrations
auth_user django_session
auth_user_groups polls_choice
auth_user_user_permissions polls_question
我想在管理界面上添加对数据库更新的实时确认。我将修改应用端的admin.py,如下所示。我认为调用models.py中的Question就可以理解为这个意思了吧。
from django.contrib import admin
from .models import Question
admin.site.register(Question)
将存储在数据库中的数据输出到HTML文件中。
那么,让我们来确认一下如何将数据库的数据输出为HTML。
另外,我想在输出数据的HTML上设置一个必须先登录才能访问的功能。
首先,我们将在项目中进行配置。请将urls.py准备如下所示。添加了★的部分是新添加的内容。
当有请求访问”http://”服务器的IP地址”:8000/polls/”时,说明将处理引导到polls应用程序(≒目录)上的urls.py文件。
# This is Project urls.py
from django.contrib import admin
from django.urls import path, include
from django.contrib.auth.decorators import login_required
from django.views.generic import TemplateView
from .views import homeView
index_view = TemplateView.as_view(template_name="index.html")
urlpatterns = [
path('admin/', admin.site.urls),
path("index/", login_required(index_view), name="index"),
path("polls/", include("polls.urls")),★追加
path("auth/", include("django.contrib.auth.urls"), name="login"),
path('', homeView.as_view(), name="home"),
]
# This is polls app urls.py
from django.urls import path, include
from django.contrib.auth.decorators import login_required
from django.views.generic import TemplateView
from . import views
from .views import QuestionList, pollsHome
app_name = 'polls'
QuestionList_view = TemplateView.as_view()
urlpatterns = [
path("questionlist/", login_required(QuestionList.as_view()), name="QuestionList"),
path("", pollsHome.as_view(), name="polls"),
]
我们将在应用程序的views.py中准备如下所示的内容。
当调用pollsHome类时,将返回templates/polls/polls_home.html给用户。当调用QuestionList类时,将调用models.py中定义和创建的Question以及templates/polls/QuestionList.html,并将其处理后返回给用户。此外,如果继承了ListView,似乎在这个时机将数据库中的数据存储在object_list列表中。这个object_list似乎是默认设置的,所以如果在意的话就输了(笑)。
# This is polls app views.py
from django.shortcuts import render
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import TemplateView, ListView
from .models import Question
# Create your views here.
class pollsHome(TemplateView):
template_name = "polls/polls_home.html"
class QuestionList(LoginRequiredMixin, ListView):
model = Question
template_name = "polls/QuestionList.html"
接下来,我们需要准备在上述中调用的两个HTML文件。
首先,在templates文件夹下准备一个名为polls的目录。
PS C:\Users\ohtsu\Documents\DjangoEnv\qiita\testPJ> cd .\templates\
PS C:\Users\ohtsu\Documents\DjangoEnv\qiita\testPJ\templates> mkdir polls
在这个层级中,准备以下内容的文件。
QuestionList.html的for循环更像是Python的语法,而不是HTML的语法。
该操作是将存储在object_list中的数据库数据按顺序一一提取出来。
<h1>polls_home.html</h1>
<a href="{% url 'polls:QuestionList' %}">質問一覧</a>
{% block main %}
{{ user.username }}さん、こんにちは。
<a href="{% url 'logout' %}">ログアウト</a>
<div class="text-center mb-5">
<h1 class="display-3 mb-5">QuestionList</h1>
<p class="text-muted fs-3">Question</p>
</div>
<div>
{% for i in object_list %}
<ul>
<li>{{ i.question_text }}</li>
</ul>
{% endfor %}
</div>
{% endblock %}
我将以以下方式修改home.html。
可以将其视为为polls应用程序创建(用户可见的)导航路径。
“polls:polls”的添加部分是指定应用程序的urls.py文件中指定的”app_name = ‘polls'”部分。后面的polls是指定应用程序的urls.py文件中指定的”path(“”, pollsHome.as_view(), name=”polls”),”部分。
<h1>Hello devProject</h1>
<a href="{% url 'login' %}">ログイン</a>
<a href="{% url 'admin:index' %}">ADMIN</a>
<a href="{% url 'polls:polls' %}">polls</a>★追加部分
考试
这次想试着做得更像一点,比如布局什么的~