我:「我想学习Python…最开始应该是先制定个TODO计划吧!」[第二章]
首先
这篇文章是续集。如果您已经阅读了之前的文章,那么阅读本文后您可能更能理解其中的内容。但是,即使您从本篇文章开始阅读也没有问题。
- ワイ「Pythonの勉強したいなァ・・・Djangoってのがあるんか」
环境信息
-
- MacBook Air (Monterey)
- Docker Compose version v2.6.1
引入
我是工○新○,一名高中生侦探。
我和小时候的朋友毛兰一起去游乐园玩,意外目击到了一处黑衣男子可疑的交易现场。
我想要过一个有趣的人生,就像这样啊~(嘿嘿)
我: “好吧,之前是用Python + Django + Docker来进行环境配置的”
我:“要做什么呢〜”
我:“对啊,果然首先要做的是传家之宝——’TODO应用’ (非常棒的)”
如果你没有读过前一篇文章的话,请跳过本章节。
本条目
我「先来温习一下吧」
-rw-r--r-- 1 user staff 155B 8 5 12:17 Dockerfile
-rw-r--r-- 1 user staff 349B 8 5 12:33 docker-compose.yml
-rwxr-xr-x 1 user staff 660B 8 10 10:00 manage.py*
-rw-r--r-- 1 user staff 24B 8 10 09:52 requirements.txt
drwxr-xr-x 8 user staff 256B 8 10 10:02 config/
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgres',
'USER': 'postgres',
'PASSWORD': 'postgres',
'HOST': 'db',
'PORT': 5432,
}
}
TIME_ZONE = 'Asia/Tokyo'
LANGUAGE_CODE = 'ja'
我:”这是稀松平常的事情呀”。
我说:“这次我们可以一边参考djangogirls之类的东西,一边进行。”
创建应用程序
我:“好像是要把开发分成不同的目录进行。”
我:“那就打指令吧。”
docker-compose exec web python manage.py startapp todo
ll total 32
-rw-r--r-- 1 user staff 155B 8 5 12:17 Dockerfile
drwxr-xr-x 8 user staff 256B 8 10 11:07 config/
-rw-r--r-- 1 user staff 349B 8 5 12:33 docker-compose.yml
-rwxr-xr-x 1 user staff 662B 8 10 11:02 manage.py*
-rw-r--r-- 1 user staff 24B 8 10 09:52 requirements.txt
drwxr-xr-x 9 user staff 288B 8 10 11:07 todo/
我: “新建了一个todo目录啊”
我:“嘿,听说需要注册我的一个新应用。”
我:“你要修改config/settings.py吗?”
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'todo.apps.TodoConfig', // この1行を追記する
]
我:“看起来这样就可以了吧。”
创建TODO表
我:看来制作桌子的时候需要定义一个模型。
我: “听说像Laravel那样的东西呢”。
我:“妈妈,好吧。那我就走了。”
from django.db import models
# Create your models here.
class Todo(models.Model):
title = models.CharField("名前", max_length=100)
description = models.TextField("タスク内容", blank=True)
def __str__(self):
return self.title
我觉得这样应该可以。
我:你没有读过官方文件,关于这个模型的详细信息。
迁移
我:一旦定义了模型,就需要创建迁移文件。
docker-compose exec web python makemigration todo
Migrations for 'todo':
todo/migrations/0001_initial.py
- Create model Todo
我:“看起来做完了,还挺简单的。”
我: “做迁移文件就是说…”
我:「要移民啦」
docker-compose exec web python migrate todo
Operations to perform:
Apply all migrations: todo
Running migrations:
Applying todo.0001_initial... OK
创建超级用户
我想确认一下我做的桌子(模型)。
我:什么什么…这是什么?
Django 管理员平台
我:“好像只需要在admin.py文件中注册一下就可以看到了。”
from django.contrib import admin
from .models import Todo
# Register your models here.
admin.site.register(Todo)
我:“这样啊。”
我: “既然说是管理员,那应该有超级用户存在吧。”
docker-compose exec web python manage.py createsuperuser
You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
psycopg2.errors.UndefinedTable: relation "auth_user" does not exist
LINE 1: ...user"."is_active", "auth_user"."date_joined" FROM "auth_user...
^
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/code/manage.py", line 22, in <module>
main()
File "/code/manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
utility.execute()
File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 413, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 354, in run_from_argv
self.execute(*args, **cmd_options)
File "/usr/local/lib/python3.9/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 79, in execute
return super().execute(*args, **options)
File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 398, in execute
output = self.handle(*args, **options)
File "/usr/local/lib/python3.9/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 100, in handle
default_username = get_default_username(database=database)
File "/usr/local/lib/python3.9/site-packages/django/contrib/auth/management/__init__.py", line 141, in get_default_username
auth_app.User._default_manager.db_manager(database).get(
File "/usr/local/lib/python3.9/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 431, in get
num = len(clone)
File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 262, in __len__
self._fetch_all()
File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 1324, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "/usr/local/lib/python3.9/site-packages/django/db/models/query.py", line 51, in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
File "/usr/local/lib/python3.9/site-packages/django/db/models/sql/compiler.py", line 1175, in execute_sql
cursor.execute(sql, params)
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 98, in execute
return super().execute(sql, params)
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 66, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python3.9/site-packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/usr/local/lib/python3.9/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "auth_user" does not exist
LINE 1: ...user"."is_active", "auth_user"."date_joined" FROM "auth_user...
我:“又是一段很长的错误文。”
You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
我: “你写着让运行python manage.py migrate”
我: “这是不是跟刚才做的不一样呢?”
docker-compose exec web python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions, todo
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK
我明白了。
我:“再试一次吧。”
docker-compose exec web python manage.py createsuperuser
ユーザー名 (leave blank to use 'root'): 好きな名前
メールアドレス: 空でok
Password:
Password (again):
Superuser created successfully.
我:做完了吗?
我:“赶快访问管理员页面。”
模板
我:接下来是可见部分的实现。
mkdir -p todo/templates/todo
touch todo/templates/todo/todo_list.html
我:“在todo目录中创建todo目录感觉有点怪。”
“为了以后轻松愉快”
我:”哇哦~”
我:“暫時先……寫一下吧。”
<html>
<head>
<title>todo</title>
</head>
<body>
<h1>hello world</h1>
</body>
</html>
「咱们说的一开始就是这个吧。」
URL的故事
我:”Django的URL是在urls.py文件中定义的。”
我: “这个不是在todo里面,而是在config那边。”
我:“如果有困难,请复制以下内容”
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('todo.urls')),
]
我:这样就可以将访问主域名直接重定向到blog.urls了。
我:“那我来创建一个blog.urls吧。”
touch todo/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.todo_list, name='todo_list'),
]
我:”使用这个,访问localhost:8000/会被重定向到todo_list.html”
创建一个视图
我:“刚刚在blog.urls中指定的view.todo_list那部分要开始实现了。”
from django.shortcuts import render
def todo_list(request):
return render(request, 'todo/todo_list.html', {})
我:“写的东西很简单。”
我: “调用一个基于render模板的函数来创建视图”
我:把经过组装后得到的值作为返回值。
我:“详细的事情以后再说,这次只是抓住氛围。”
充分确认
我:暂且就这样吧
我: “你好,世界!”
??・观众:「太吵了」
尝试用Django ORM将已注册的Todo传递给模板。
我:“这是一个Todo应用,先从确认已登记的Todo开始吧。”
我:“在这里没有进行数据注册的人,无论什么都可以注册。”
我:“首先要确认能否正确获取数据。”
docker-compose exec web python manage.py shell
// 対話モードに入る
// 行ごとに入力・エンターキーを押してください
>>> from todo.models import Todo
>>> Todo.objects.all()
<QuerySet [<Todo: sample>]>
我:“看起来没问题。”
我:“那么我们实际上把它作为逻辑写出来吧。”
from django.shortcuts import render
from .models import Todo
def todo_list(request):
todos = Todo.objects.all()
return render(request, 'todo/todo_list.html', {'todo': todos})
显示传输的数据
我:“Django有模板标签吗?”
以下内容来自Django Girls:
模板标签是什么?
在HTML中,实际上不能直接编写Python代码,因为浏览器无法理解。浏览器只能理解HTML。HTML通常是静态的,而我们知道Python可以做更加动态的事情。
Django模板标签可以在HTML中嵌入类似Python的代码,可以更快、更简单地创建动态网站!
我听说了
我:那就写出来给我看看吧。
<html>
<head>
<title>todo</title>
</head>
<body>
<h1>hello world</h1>
{{ todo }} // 追記部分
</body>
</html>
我:用这样的{{ 提供的数据 }}似乎可以写出来。
我:”那么来访问一下~”
我:“这是一个列表,所以应该可以很方便地用循环取出。”
<html>
<head>
<title>todo</title>
</head>
<body>
<h1>hello world</h1>
{% for td in todo %}
<div>
<p>タスク名:{{ td.title}}</p>
<p>タスク内容:{{ td.description}}</p>
</div>
{% endfor %}
</body>
</html>
我:「列表的内容应该是在models中注册的表的列,所以应该是这样的样子吧。」
我:那么确认吧。
让我们用CSS创建可爱时尚的效果吧。
我:“暂时显示了数据,不过…”
我:看起来很无聊,味道也没有。
我:“这里是CSS小姐努力的地方哦。”
我:你难道以为……
我:“我超爱 tailwindcss !!”
我:“顺带一提,如果要编写普通的CSS代码,可以参考这里。”
我:立刻写给我吧
<html>
<head>
<title>todo</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<h1 class="text-red-500 text-5xl mb-5">hello world</h1>
<div class="mx-auto w-9/12">
{% for td in todo %}
<div class="border-4 p-8">
<p class="text-2xl border-b-2 mb-2">タスク名:{{ td.title}}</p>
<p>タスク内容:{{ td.description}}</p>
</div>
{% endfor %}
</div>
</body>
</html>
我:“这样的感觉。”
我呢,…
我:总之就这样了行吗?
我「今天已经累死我了」
我: “接下来我们要让这个画面可以进行注册和删除操作哦~”
最終的に
非常感谢您阅读到这里,这是继上次之后的笨拙长篇文章。
另外,在前一篇文章中,我们也收到了一些反响,我觉得写成文章是值得的,同时也反省了自己。
我会抽时间对文章进行修正,所以请您谅解。
如果有任何问题或疑问,请随时在评论区留言或通过Twitter联系我们,将不胜感激。
这次我们涉及了Django的各种功能,并成功展示了数据库的信息。
下一次就像Y君所说的那样。
-
- 登録機能
-
- 削除機能
- デザインの改修
计划有三个部分。
下一次再见。