我试着学习了Django教程

编写你的第一个Django应用程序,第一部分¶

首先,我被卡在了无法使用 django-admin 的问题上。虽然有人说只需通过 pip install django 安装就行,但实际上没用。原来必须预先安装 virtualenv。

python3 -m venv venv
. venv/bin/activate
pip install django
django-admin version

因为已准备就绪,所以继续进行原版教程的学习。

$ python -m django --version
3.1.6

$ django-admin startproject mysite

$ ll
total 4.0K
drwxr-xr-x  4 user1 user1   32 2021-02-05 14:38:27 .
drwxrwxrwx 17 user1 user1 4.0K 2021-02-05 14:11:33 ..
drwxr-xr-x  3 user1 user1   37 2021-02-05 14:38:21 mysite
drwxr-xr-x  5 user1 user1  100 2021-02-05 14:34:16 venv

认真地学习教程,并了解文件结构。

manage.py
mysite/
    __init__.py
    settings.py
    urls.py
    asgi.py
    wsgi.py

我关注的地方是…项目的形式。

我现在创建了一个名为mysite的项目,这是一个应用程序,对吗?

mysite/settings.py: 这个Django项目的设置/配置文件。Django的设置文件将向您介绍所有关于设置的工作方式的信息。

settings.py是mysite的设置文件。但是manage.py属于root目录。
跟我想的有点不一样。

ASGI、WSGI是关于Web服务器的问题吗?我不太清楚,所以暂时跳过。

运行命令 “python manage.py runserver”。

出现了无数次错误。

django.core.exceptions.ImproperlyConfigured: 需要SQLite 3.8.3或更高版本(发现3.7.17)。

好的,这是一个数据库。

编写您的第一个Django应用程序,第2部分

数据库

DB的设置在这里:https://docs.djangoproject.com/en/3.1/ref/databases/#mysql-notes。

CREATE DATABASE django CHARACTER SET utf8;
CREATE USER 'django'@'%' IDENTIFIED WITH mysql_native_password AS '***';
GRANT ALL PRIVILEGES ON *.* TO 'django'@'%' REQUIRE NONE WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;
CREATE DATABASE IF NOT EXISTS `django`;
GRANT ALL PRIVILEGES ON `django`.* TO 'django'@'%';GRANT ALL PRIVILEGES ON `django\_%`.* TO 'django'@'%';

    settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'OPTIONS': {
            'read_default_file': '/kc/my.cnf',
        },
    }
}

我的.cnf

[client]
database = db.example.com
user = django
password = django
default-character-set = utf8

在Python环境中,使用pip安装mysqlclient。

因为完全不看我的.cnf文件,所以我直接修改了。


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django',
        'USER': "django",
        'PASSWORD': "django",
        'HOST': "db.example.com",
        'PORT': 3306,
        'OPTIONS': {
            'sql_mode': 'STRICT_TRANS_TABLES',
            'charset': 'utf8mb4',
            'init_command': 'SET '
                            'character_set_connection=utf8mb4,'
                            'collation_connection=utf8_general_ci'
        }
    }
}

运行命令 python manage.py migrate

MySQL > 显示表;
+—————————-+
| Tables_in_django |
+—————————-+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+—————————-+
共 10 行(0.07 秒)

完成了!

运行服务器

运行命令 “python manage.py runserver”。

可以在浏览器上看到!

安装成功了!恭喜!

现在你的环境已经设置好了,一个“项目”,你可以开始工作了。

嗯。现在这个指的是一个”项目”吗?

我的网站下面的mysite是什么东西。

python manage.py startapp polls

按照教程的指示创建文件。由于之前没有 polls/urls.py 这个文件,所以我创建了它。

以下的中文翻譯如下:有趣的是

每当Django遇到include()函数时,它会截取与之前相匹配的URL的部分,并将剩下的字符串发送给包含的URLconf以进行进一步处理。

而且只写了一个 path(”) ,却被识别为 /polls。

只有了解Django,才能做到这一点。能够直观地实现是非常棒的。

撰写关于调查的模型

类型错误:init()缺少一个必需的位置参数’on_delete’,因此更改后成功通过。


class Choise(models.Model):
    question = models.ForeignKey(
        Question,
        on_delete=models.CASCADE
    )
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

运行命令 “python manage.py makemigrations polls” 后,会生成以下文件:polls/migrations/0001_initial.py

原文: sqlかと思ったらpythonなんだな。
Paraphrased: 我以为是sql,原来是python啊。


    operations = [
        migrations.CreateModel(
            name='Question',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('question_text', models.CharField(max_length=200)),
                ('pub_date', models.DateTimeField(verbose_name='date published')),
            ],
        ),

是不是指的是创建模型的事情呢,可能是初始创建吧。

那么,就可以预览一下SQL的内容了。如果无法直接将其迁移到生产环境(如PaaS等情况),可以直接将这个SQL语句传送到数据库中即可!

$ python manage.py sqlmigrate polls 0001
]--
-- Create model Question
--
CREATE TABLE `polls_question` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `question_text` varchar(200) NOT NULL, `pub_date` datetime(6) NOT NULL);
--
-- Create model Choise
--
CREATE TABLE `polls_choise` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `choice_text` varchar(200) NOT NULL, `votes` integer NOT NULL, `question_id` integer NOT NULL);
ALTER TABLE `polls_choise` ADD CONSTRAINT `polls_choise_question_id_4bd8457d_fk_polls_question_id` FOREIGN KEY (`question_id`) REFERENCES `polls_question` (`id`);

这个还没有在数据库中做出任何更改。

只执行迁移操作,表就创建好了!

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
  Applying polls.0001_initial... OK

我立即发现了一个拼写错误,把Choice误写成了Choise,所以进行了修改。

修改models.py文件一个字符。

class Choice(models.Model):
    question = models.ForeignKey(
        Question,
        on_delete=models.CASCADE
    )
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

python manage.py makemigrations
python manage.py sqlmigrate polls 0002
python manage.py migrate

仅需这样一个命令:RENAME TABLE polls_choise TO polls_choice; 就可以完成执行!!!太方便了!真是太方便了!!!

使用manage.py打开shell界面

这个调试工具看起来很方便!当SQL不通过时,用这个工具来尝试似乎会很好。虽然一直到django.setup()都有点烦人,但也没办法。

$ python manage.py shell
>>> import django
>>> django.setup()         <-----ここまで決り文句
>>>
>>> from polls.models import Question, Choice              <-----使うtable/model
>>> Question.objects.all()
<QuerySet []>

# insert
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
>>> q.save
<bound method Model.save of <Question: Question object (None)>>
>>> q.save()

# insertされたPKがそのままのobjectで見れる!
>>> q.id
1
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2021, 3, 9, 4, 42, 28, 899072, tzinfo=<UTC>)

# updateしてみる
>>> q.question_text = "What's up"
>>> q.save()
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>

只知道pk=1的话很不方便,我想知道这里的!

给模型加上字符串!!

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

    def __str__(self):
        return self.question_text

需要重新启动 shell 才能生效。

$ python manage.py shell
Python 3.7.7 (default, Jul 16 2020, 18:28:35)
[Clang 10.0.1 (clang-1001.0.46.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import django
>>> django.setup()
>>> from polls.models import *
>>> Question.objects.all()
<QuerySet [<Question: What's up>]>       <------- テキストが見えた!

查询中可以使用 pk 这个字。

表中只有一个名为 id 的列,但是可以使用 pk 来表示 id=1 的意思。很方便!

>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True

在创建relations的记录时,没有.save()方法。

>>> q.choice_set.create(choice_text='Not much', votes=0)

这个操作一执行就会被提交。不知道有什么区别,也不知道”choice_set”这个词是从哪里来的,完全不明白。可能是在进行关联时的一个规则吧,肯定是。

编写你的第一个Django应用,第2部分

激活管理员

按照教程完成后,可以操作模型时能够看到记录的历史,真是太厉害了。

python manage.py createsuperuser

然后,您可以通过/login进入内部。

http://127.0.0.1:8000/login (请将此链接复制到浏览器地址栏中)

如何实现呢? → DB中有更改日志。

SELECT * FROM `django_admin_log`

可能只有通过管理员操作才会留下记录。用途不太明确。

通过 fieldsets 对 admin panel 进行可视化调整,在 column 中添加 HTML 的 header。

这里似乎不会被使用,所以跳过阅读似乎是个好主意…

编写你的第一个Django应用,第三部分¶

创建HTML视图。虽然不太需要作为API服务器,但为了基础知识还是做一下吧。

urlpatterns = [
    url(r'^$', views.index, name='index'),
]

这个正则表达式不起作用,是怎么回事呢?当我想到是什么原因的时候,发现输入的内容完全不同。
不是用path(),而是用url()吗?
直接替换文件后就可以工作了。

我不想使用Jinja,但姑且先用它。Django会自动读取模板目录。
通过context将值传递给template.render()。
然后链接会自动添加。
啊,原来是在Jinja中使用对象来创建的。

原来如此。

实时渲染

这个和那个是一样的。

def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    template = loader.get_template('polls/index.html')
    context = {
        'latest_question_list': latest_question_list,
    }
    return HttpResponse(template.render(context, request))
def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    return render(request, 'polls/index.html', context)

这种相同的写法让人很难受。

404

当设置为404时

在/polls/13/处不存在。

是。

找不到页面(404)

在…之后, …zhī

问题并不存在

教我。

404快捷方式

这两个是一样的。

def detail(request, question_id):
    try:
        question = Question.objects.get(pk=question_id)
    except Question.DoesNotExist:
        raise Http404("Question does not exist")
    return render(request, 'polls/detail.html', {'question': question})


def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})


错误信息是:没有问题与给定的查询相匹配。

成为了

view這樣應該可以

编写你的第一个Django应用程序,第四部分¶

由于是关于Jinja的话题,完全跳过。

编写你的第一个Django应用程序,第5部分

放置 polls/tests.py

运行命令`python manage.py test polls`的中文本地化版本:

可以进行测试。有趣的是,只需使用 Question(pub_date=time) 就可以创建一个临时的虚拟数据库记录。

视图的测试是什么?

从django.core.urlresolvers模块导入reverse函数。

因为这个被绊倒了,所以我决定跳过它。

编写你的第一个Django应用,第6部分

CSS追加的方式

创建 /polls/static/polls/styles.css.

{% 加载静态文件 %}

读取。

嗯,我略有了解 Django。

广告
将在 10 秒后关闭
bannerAds