我:「我想学习Python…最开始应该是先制定个TODO计划吧!」[第二章]

首先

这篇文章是续集。如果您已经阅读了之前的文章,那么阅读本文后您可能更能理解其中的内容。但是,即使您从本篇文章开始阅读也没有问题。

    ワイ「Pythonの勉強したいなァ・・・Djangoってのがあるんか」

环境信息

    • MacBook Air (Monterey)

 

    Docker Compose version v2.6.1

引入

我是工○新○,一名高中生侦探。

我和小时候的朋友毛兰一起去游乐园玩,意外目击到了一处黑衣男子可疑的交易现场。

 

我想要过一个有趣的人生,就像这样啊~(嘿嘿)

我: “好吧,之前是用Python + Django + Docker来进行环境配置的”

我:“要做什么呢〜”

我:“对啊,果然首先要做的是传家之宝——’TODO应用’ (非常棒的)”

如果你没有读过前一篇文章的话,请跳过本章节。

スクリーンショット 2022-08-10 10.54.06.png

本条目

我「先来温习一下吧」

-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.

我:做完了吗?

我:“赶快访问管理员页面。”

スクリーンショット 2022-08-10 11.53.58.png
スクリーンショット 2022-08-10 11.54.35.png
スクリーンショット 2022-08-10 12.59.16.png

模板

我:接下来是可见部分的实现。

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模板的函数来创建视图”

我:把经过组装后得到的值作为返回值。

我:“详细的事情以后再说,这次只是抓住氛围。”

充分确认

我:暂且就这样吧

スクリーンショット 2022-08-10 12.44.52.png

我: “你好,世界!”

??・观众:「太吵了」

尝试用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>

我:用这样的{{ 提供的数据 }}似乎可以写出来。

我:”那么来访问一下~”

スクリーンショット 2022-08-10 13.16.47.png

我:“这是一个列表,所以应该可以很方便地用循环取出。”

<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中注册的表的列,所以应该是这样的样子吧。」

我:那么确认吧。

スクリーンショット 2022-08-10 13.23.16.png

让我们用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>

我:“这样的感觉。”

スクリーンショット 2022-08-10 13.41.41.png

我呢,…

我:总之就这样了行吗?

我「今天已经累死我了」

我: “接下来我们要让这个画面可以进行注册和删除操作哦~”

最終的に

非常感谢您阅读到这里,这是继上次之后的笨拙长篇文章。

另外,在前一篇文章中,我们也收到了一些反响,我觉得写成文章是值得的,同时也反省了自己。
我会抽时间对文章进行修正,所以请您谅解。

如果有任何问题或疑问,请随时在评论区留言或通过Twitter联系我们,将不胜感激。

这次我们涉及了Django的各种功能,并成功展示了数据库的信息。

下一次就像Y君所说的那样。

    • 登録機能

 

    • 削除機能

 

    デザインの改修

计划有三个部分。

下一次再见。

广告
将在 10 秒后关闭
bannerAds